2 * Copyright 2008-2009 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "mshtml_private.h"
31 #include "htmlevent.h"
32 #include "htmlscript.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
39 LISTENER_TYPE_CAPTURE
,
41 LISTENER_TYPE_ONEVENT
,
42 LISTENER_TYPE_ATTACHED
52 struct wine_rb_entry entry
;
53 struct list listeners
;
55 } listener_container_t
;
74 static const WCHAR
*event_types
[] = {
92 /* Use Gecko default listener (it's registered on window object for DOM nodes). */
93 #define EVENT_DEFAULTLISTENER 0x0001
94 /* Register Gecko listener on target itself (unlike EVENT_DEFAULTLISTENER). */
95 #define EVENT_BIND_TO_TARGET 0x0002
96 /* Event bubbles by default (unless explicitly specified otherwise). */
97 #define EVENT_BUBBLES 0x0004
98 /* Event is cancelable by default (unless explicitly specified otherwise). */
99 #define EVENT_CANCELABLE 0x0008
100 /* Event may have default handler (so we always have to register Gecko listener). */
101 #define EVENT_HASDEFAULTHANDLERS 0x0020
102 /* Ecent is not supported properly, print FIXME message when it's used. */
103 #define EVENT_FIXME 0x0040
105 /* mouse event flags for fromElement and toElement implementation */
106 #define EVENT_MOUSE_TO_RELATED 0x0100
107 #define EVENT_MOUSE_FROM_RELATED 0x0200
109 static const event_info_t event_info
[] = {
110 {L
"abort", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONABORT
,
111 EVENT_BIND_TO_TARGET
},
112 {L
"beforeactivate", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONBEFOREACTIVATE
,
113 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
114 {L
"beforeunload", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONBEFOREUNLOAD
,
115 EVENT_DEFAULTLISTENER
| EVENT_CANCELABLE
},
116 {L
"blur", EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONBLUR
,
117 EVENT_DEFAULTLISTENER
},
118 {L
"change", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONCHANGE
,
119 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
},
120 {L
"click", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONCLICK
,
121 EVENT_DEFAULTLISTENER
| EVENT_HASDEFAULTHANDLERS
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
122 {L
"contextmenu", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONCONTEXTMENU
,
123 EVENT_BUBBLES
| EVENT_CANCELABLE
},
124 {L
"dataavailable", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONDATAAVAILABLE
,
125 EVENT_FIXME
| EVENT_BUBBLES
},
126 {L
"dblclick", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONDBLCLICK
,
127 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
128 {L
"DOMContentLoaded", EVENT_TYPE_EVENT
, 0,
129 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
130 {L
"drag", EVENT_TYPE_DRAG
, DISPID_EVMETH_ONDRAG
,
131 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
132 {L
"dragstart", EVENT_TYPE_DRAG
, DISPID_EVMETH_ONDRAGSTART
,
133 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
134 {L
"error", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONERROR
,
135 EVENT_BIND_TO_TARGET
},
136 {L
"focus", EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONFOCUS
,
137 EVENT_DEFAULTLISTENER
},
138 {L
"focusin", EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONFOCUSIN
,
140 {L
"focusout", EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONFOCUSOUT
,
142 {L
"help", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONHELP
,
143 EVENT_BUBBLES
| EVENT_CANCELABLE
},
144 {L
"input", EVENT_TYPE_EVENT
, DISPID_UNKNOWN
,
145 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
},
146 {L
"keydown", EVENT_TYPE_KEYBOARD
, DISPID_EVMETH_ONKEYDOWN
,
147 EVENT_DEFAULTLISTENER
| EVENT_HASDEFAULTHANDLERS
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
148 {L
"keypress", EVENT_TYPE_KEYBOARD
, DISPID_EVMETH_ONKEYPRESS
,
149 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
150 {L
"keyup", EVENT_TYPE_KEYBOARD
, DISPID_EVMETH_ONKEYUP
,
151 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
152 {L
"load", EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONLOAD
,
153 EVENT_BIND_TO_TARGET
},
154 {L
"message", EVENT_TYPE_MESSAGE
, DISPID_EVMETH_ONMESSAGE
,
156 {L
"mousedown", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEDOWN
,
157 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
158 {L
"mousemove", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEMOVE
,
159 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
| EVENT_MOUSE_FROM_RELATED
},
160 {L
"mouseout", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEOUT
,
161 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
| EVENT_MOUSE_TO_RELATED
},
162 {L
"mouseover", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEOVER
,
163 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
| EVENT_MOUSE_FROM_RELATED
},
164 {L
"mouseup", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEUP
,
165 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
166 {L
"mousewheel", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEWHEEL
,
168 {L
"msthumbnailclick", EVENT_TYPE_MOUSE
, DISPID_EVPROP_ONMSTHUMBNAILCLICK
,
170 {L
"paste", EVENT_TYPE_CLIPBOARD
, DISPID_EVMETH_ONPASTE
,
171 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
172 {L
"readystatechange", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONREADYSTATECHANGE
,
174 {L
"resize", EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONRESIZE
,
175 EVENT_DEFAULTLISTENER
},
176 {L
"scroll", EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONSCROLL
,
177 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
/* FIXME: not for elements */},
178 {L
"selectionchange", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONSELECTIONCHANGE
,
180 {L
"selectstart", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONSELECTSTART
,
181 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
182 {L
"submit", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONSUBMIT
,
183 EVENT_DEFAULTLISTENER
| EVENT_HASDEFAULTHANDLERS
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
184 {L
"unload", EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONUNLOAD
,
188 static eventid_t
str_to_eid(const WCHAR
*str
)
192 for(i
=0; i
< ARRAY_SIZE(event_info
); i
++) {
193 if(!wcscmp(event_info
[i
].name
, str
))
200 static eventid_t
attr_to_eid(const WCHAR
*str
)
204 if((str
[0] != 'o' && str
[0] != 'O') || (str
[1] != 'n' && str
[1] != 'N'))
207 for(i
=0; i
< ARRAY_SIZE(event_info
); i
++) {
208 if(!wcscmp(event_info
[i
].name
, str
+2) && event_info
[i
].dispid
)
215 static listener_container_t
*get_listener_container(EventTarget
*event_target
, const WCHAR
*type
, BOOL alloc
)
217 const event_target_vtbl_t
*vtbl
;
218 listener_container_t
*container
;
219 struct wine_rb_entry
*entry
;
223 entry
= wine_rb_get(&event_target
->handler_map
, type
);
225 return WINE_RB_ENTRY_VALUE(entry
, listener_container_t
, entry
);
229 eid
= str_to_eid(type
);
230 if(eid
!= EVENTID_LAST
&& (event_info
[eid
].flags
& EVENT_FIXME
))
231 FIXME("unimplemented event %s\n", debugstr_w(event_info
[eid
].name
));
233 type_len
= lstrlenW(type
);
234 container
= heap_alloc(FIELD_OFFSET(listener_container_t
, type
[type_len
+1]));
237 memcpy(container
->type
, type
, (type_len
+ 1) * sizeof(WCHAR
));
238 list_init(&container
->listeners
);
239 vtbl
= dispex_get_vtbl(&event_target
->dispex
);
241 vtbl
->bind_event(&event_target
->dispex
, eid
);
243 FIXME("Unsupported event binding on target %p\n", event_target
);
245 wine_rb_put(&event_target
->handler_map
, container
->type
, &container
->entry
);
249 static void remove_event_listener(EventTarget
*event_target
, const WCHAR
*type_name
, listener_type_t type
, IDispatch
*function
)
251 listener_container_t
*container
;
252 event_listener_t
*listener
;
254 container
= get_listener_container(event_target
, type_name
, FALSE
);
258 LIST_FOR_EACH_ENTRY(listener
, &container
->listeners
, event_listener_t
, entry
) {
259 if(listener
->function
== function
&& listener
->type
== type
) {
260 IDispatch_Release(listener
->function
);
261 list_remove(&listener
->entry
);
268 static HRESULT
get_gecko_target(IEventTarget
*,nsIDOMEventTarget
**);
272 IHTMLEventObj IHTMLEventObj_iface
;
277 VARIANT return_value
;
280 static inline HTMLEventObj
*impl_from_IHTMLEventObj(IHTMLEventObj
*iface
)
282 return CONTAINING_RECORD(iface
, HTMLEventObj
, IHTMLEventObj_iface
);
285 static HRESULT WINAPI
HTMLEventObj_QueryInterface(IHTMLEventObj
*iface
, REFIID riid
, void **ppv
)
287 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
289 TRACE("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
291 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
292 *ppv
= &This
->IHTMLEventObj_iface
;
293 }else if(IsEqualGUID(&IID_IHTMLEventObj
, riid
)) {
294 *ppv
= &This
->IHTMLEventObj_iface
;
295 }else if(dispex_query_interface(&This
->dispex
, riid
, ppv
)) {
296 return *ppv
? S_OK
: E_NOINTERFACE
;
299 WARN("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
300 return E_NOINTERFACE
;
303 IUnknown_AddRef((IUnknown
*)*ppv
);
307 static ULONG WINAPI
HTMLEventObj_AddRef(IHTMLEventObj
*iface
)
309 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
310 LONG ref
= InterlockedIncrement(&This
->ref
);
312 TRACE("(%p) ref=%d\n", This
, ref
);
317 static ULONG WINAPI
HTMLEventObj_Release(IHTMLEventObj
*iface
)
319 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
320 LONG ref
= InterlockedDecrement(&This
->ref
);
322 TRACE("(%p) ref=%d\n", This
, ref
);
326 IDOMEvent_Release(&This
->event
->IDOMEvent_iface
);
327 release_dispex(&This
->dispex
);
334 static HRESULT WINAPI
HTMLEventObj_GetTypeInfoCount(IHTMLEventObj
*iface
, UINT
*pctinfo
)
336 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
337 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
340 static HRESULT WINAPI
HTMLEventObj_GetTypeInfo(IHTMLEventObj
*iface
, UINT iTInfo
,
341 LCID lcid
, ITypeInfo
**ppTInfo
)
343 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
344 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
347 static HRESULT WINAPI
HTMLEventObj_GetIDsOfNames(IHTMLEventObj
*iface
, REFIID riid
,
348 LPOLESTR
*rgszNames
, UINT cNames
,
349 LCID lcid
, DISPID
*rgDispId
)
351 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
352 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
356 static HRESULT WINAPI
HTMLEventObj_Invoke(IHTMLEventObj
*iface
, DISPID dispIdMember
,
357 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
358 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
360 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
361 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
362 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
365 static HRESULT WINAPI
HTMLEventObj_get_srcElement(IHTMLEventObj
*iface
, IHTMLElement
**p
)
367 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
369 TRACE("(%p)->(%p)\n", This
, p
);
376 return IDOMEvent_get_srcElement(&This
->event
->IDOMEvent_iface
, p
);
379 static HRESULT WINAPI
HTMLEventObj_get_altKey(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
381 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
382 cpp_bool ret
= FALSE
;
384 TRACE("(%p)->(%p)\n", This
, p
);
386 if(This
->event
&& This
->event
->mouse_event
)
387 return IDOMMouseEvent_get_altKey(&This
->event
->IDOMMouseEvent_iface
, p
);
389 if(This
->event
&& This
->event
->keyboard_event
)
390 return IDOMKeyboardEvent_get_altKey(&This
->event
->IDOMKeyboardEvent_iface
, p
);
392 *p
= variant_bool(ret
);
396 static HRESULT WINAPI
HTMLEventObj_get_ctrlKey(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
398 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
399 cpp_bool ret
= FALSE
;
401 TRACE("(%p)->(%p)\n", This
, p
);
403 if(This
->event
&& This
->event
->mouse_event
)
404 return IDOMMouseEvent_get_ctrlKey(&This
->event
->IDOMMouseEvent_iface
, p
);
406 if(This
->event
&& This
->event
->keyboard_event
)
407 return IDOMKeyboardEvent_get_ctrlKey(&This
->event
->IDOMKeyboardEvent_iface
, p
);
409 *p
= variant_bool(ret
);
413 static HRESULT WINAPI
HTMLEventObj_get_shiftKey(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
415 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
416 cpp_bool ret
= FALSE
;
418 TRACE("(%p)->(%p)\n", This
, p
);
420 if(This
->event
&& This
->event
->mouse_event
)
421 return IDOMMouseEvent_get_shiftKey(&This
->event
->IDOMMouseEvent_iface
, p
);
423 if(This
->event
&& This
->event
->keyboard_event
)
424 return IDOMKeyboardEvent_get_shiftKey(&This
->event
->IDOMKeyboardEvent_iface
, p
);
426 *p
= variant_bool(ret
);
430 static HRESULT WINAPI
HTMLEventObj_put_returnValue(IHTMLEventObj
*iface
, VARIANT v
)
432 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
434 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&v
));
436 if(V_VT(&v
) != VT_BOOL
) {
437 FIXME("unsupported value %s\n", debugstr_variant(&v
));
438 return DISP_E_BADVARTYPE
;
441 This
->return_value
= v
;
442 if(!V_BOOL(&v
) && This
->event
)
443 IDOMEvent_preventDefault(&This
->event
->IDOMEvent_iface
);
447 static HRESULT WINAPI
HTMLEventObj_get_returnValue(IHTMLEventObj
*iface
, VARIANT
*p
)
449 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
451 TRACE("(%p)->(%p)\n", This
, p
);
454 return VariantCopy(p
, &This
->return_value
);
457 static HRESULT WINAPI
HTMLEventObj_put_cancelBubble(IHTMLEventObj
*iface
, VARIANT_BOOL v
)
459 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
461 TRACE("(%p)->(%x)\n", This
, v
);
464 IDOMEvent_stopPropagation(&This
->event
->IDOMEvent_iface
);
468 static HRESULT WINAPI
HTMLEventObj_get_cancelBubble(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
470 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
472 TRACE("(%p)->(%p)\n", This
, p
);
474 *p
= variant_bool(This
->event
&& This
->event
->stop_propagation
);
478 static HRESULT WINAPI
HTMLEventObj_get_fromElement(IHTMLEventObj
*iface
, IHTMLElement
**p
)
480 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
482 TRACE("(%p)->(%p)\n", This
, p
);
484 if(This
->event
&& This
->event
->mouse_event
)
485 return IDOMMouseEvent_get_fromElement(&This
->event
->IDOMMouseEvent_iface
, p
);
491 static HRESULT WINAPI
HTMLEventObj_get_toElement(IHTMLEventObj
*iface
, IHTMLElement
**p
)
493 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
495 TRACE("(%p)->(%p)\n", This
, p
);
497 if(This
->event
&& This
->event
->mouse_event
)
498 return IDOMMouseEvent_get_toElement(&This
->event
->IDOMMouseEvent_iface
, p
);
504 static HRESULT WINAPI
HTMLEventObj_put_keyCode(IHTMLEventObj
*iface
, LONG v
)
506 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
507 FIXME("(%p)->(%d)\n", This
, v
);
511 static HRESULT WINAPI
HTMLEventObj_get_keyCode(IHTMLEventObj
*iface
, LONG
*p
)
513 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
515 TRACE("(%p)->(%p)\n", This
, p
);
517 if(This
->event
&& This
->event
->keyboard_event
)
518 return IDOMKeyboardEvent_get_keyCode(&This
->event
->IDOMKeyboardEvent_iface
, p
);
524 static HRESULT WINAPI
HTMLEventObj_get_button(IHTMLEventObj
*iface
, LONG
*p
)
526 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
529 TRACE("(%p)->(%p)\n", This
, p
);
531 if(This
->event
&& This
->event
->mouse_event
) {
533 hres
= IDOMMouseEvent_get_button(&This
->event
->IDOMMouseEvent_iface
, &button
);
542 static HRESULT WINAPI
HTMLEventObj_get_type(IHTMLEventObj
*iface
, BSTR
*p
)
544 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
546 TRACE("(%p)->(%p)\n", This
, p
);
553 return IDOMEvent_get_type(&This
->event
->IDOMEvent_iface
, p
);
556 static HRESULT WINAPI
HTMLEventObj_get_qualifier(IHTMLEventObj
*iface
, BSTR
*p
)
558 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
560 FIXME("(%p)->(%p)\n", This
, p
);
566 static HRESULT WINAPI
HTMLEventObj_get_reason(IHTMLEventObj
*iface
, LONG
*p
)
568 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
570 FIXME("(%p)->(%p)\n", This
, p
);
576 static HRESULT WINAPI
HTMLEventObj_get_x(IHTMLEventObj
*iface
, LONG
*p
)
578 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
581 TRACE("(%p)->(%p)\n", This
, p
);
583 if(This
->event
&& This
->event
->ui_event
) {
586 /* NOTE: pageX is not exactly right here. */
587 nsres
= nsIDOMUIEvent_GetPageX(This
->event
->ui_event
, &x
);
588 assert(nsres
== NS_OK
);
595 static HRESULT WINAPI
HTMLEventObj_get_y(IHTMLEventObj
*iface
, LONG
*p
)
597 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
600 TRACE("(%p)->(%p)\n", This
, p
);
602 if(This
->event
&& This
->event
->ui_event
) {
605 /* NOTE: pageY is not exactly right here. */
606 nsres
= nsIDOMUIEvent_GetPageY(This
->event
->ui_event
, &y
);
607 assert(nsres
== NS_OK
);
614 static HRESULT WINAPI
HTMLEventObj_get_clientX(IHTMLEventObj
*iface
, LONG
*p
)
616 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
618 TRACE("(%p)->(%p)\n", This
, p
);
620 if(This
->event
&& This
->event
->mouse_event
)
621 return IDOMMouseEvent_get_clientX(&This
->event
->IDOMMouseEvent_iface
, p
);
627 static HRESULT WINAPI
HTMLEventObj_get_clientY(IHTMLEventObj
*iface
, LONG
*p
)
629 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
631 TRACE("(%p)->(%p)\n", This
, p
);
633 if(This
->event
&& This
->event
->mouse_event
)
634 return IDOMMouseEvent_get_clientY(&This
->event
->IDOMMouseEvent_iface
, p
);
640 static HRESULT WINAPI
HTMLEventObj_get_offsetX(IHTMLEventObj
*iface
, LONG
*p
)
642 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
644 TRACE("(%p)->(%p)\n", This
, p
);
646 if(This
->event
&& This
->event
->mouse_event
)
647 return IDOMMouseEvent_get_offsetX(&This
->event
->IDOMMouseEvent_iface
, p
);
653 static HRESULT WINAPI
HTMLEventObj_get_offsetY(IHTMLEventObj
*iface
, LONG
*p
)
655 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
657 TRACE("(%p)->(%p)\n", This
, p
);
659 if(This
->event
&& This
->event
->mouse_event
)
660 return IDOMMouseEvent_get_offsetY(&This
->event
->IDOMMouseEvent_iface
, p
);
666 static HRESULT WINAPI
HTMLEventObj_get_screenX(IHTMLEventObj
*iface
, LONG
*p
)
668 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
670 TRACE("(%p)->(%p)\n", This
, p
);
672 if(This
->event
&& This
->event
->mouse_event
)
673 return IDOMMouseEvent_get_screenX(&This
->event
->IDOMMouseEvent_iface
, p
);
679 static HRESULT WINAPI
HTMLEventObj_get_screenY(IHTMLEventObj
*iface
, LONG
*p
)
681 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
683 TRACE("(%p)->(%p)\n", This
, p
);
685 if(This
->event
&& This
->event
->mouse_event
)
686 return IDOMMouseEvent_get_screenY(&This
->event
->IDOMMouseEvent_iface
, p
);
692 static HRESULT WINAPI
HTMLEventObj_get_srcFilter(IHTMLEventObj
*iface
, IDispatch
**p
)
694 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
696 FIXME("(%p)->(%p)\n", This
, p
);
702 static const IHTMLEventObjVtbl HTMLEventObjVtbl
= {
703 HTMLEventObj_QueryInterface
,
705 HTMLEventObj_Release
,
706 HTMLEventObj_GetTypeInfoCount
,
707 HTMLEventObj_GetTypeInfo
,
708 HTMLEventObj_GetIDsOfNames
,
710 HTMLEventObj_get_srcElement
,
711 HTMLEventObj_get_altKey
,
712 HTMLEventObj_get_ctrlKey
,
713 HTMLEventObj_get_shiftKey
,
714 HTMLEventObj_put_returnValue
,
715 HTMLEventObj_get_returnValue
,
716 HTMLEventObj_put_cancelBubble
,
717 HTMLEventObj_get_cancelBubble
,
718 HTMLEventObj_get_fromElement
,
719 HTMLEventObj_get_toElement
,
720 HTMLEventObj_put_keyCode
,
721 HTMLEventObj_get_keyCode
,
722 HTMLEventObj_get_button
,
723 HTMLEventObj_get_type
,
724 HTMLEventObj_get_qualifier
,
725 HTMLEventObj_get_reason
,
728 HTMLEventObj_get_clientX
,
729 HTMLEventObj_get_clientY
,
730 HTMLEventObj_get_offsetX
,
731 HTMLEventObj_get_offsetY
,
732 HTMLEventObj_get_screenX
,
733 HTMLEventObj_get_screenY
,
734 HTMLEventObj_get_srcFilter
737 static inline HTMLEventObj
*unsafe_impl_from_IHTMLEventObj(IHTMLEventObj
*iface
)
739 return iface
->lpVtbl
== &HTMLEventObjVtbl
? impl_from_IHTMLEventObj(iface
) : NULL
;
742 static const tid_t HTMLEventObj_iface_tids
[] = {
747 static dispex_static_data_t HTMLEventObj_dispex
= {
750 HTMLEventObj_iface_tids
753 static HTMLEventObj
*alloc_event_obj(DOMEvent
*event
)
755 HTMLEventObj
*event_obj
;
757 event_obj
= heap_alloc_zero(sizeof(*event_obj
));
761 event_obj
->IHTMLEventObj_iface
.lpVtbl
= &HTMLEventObjVtbl
;
763 event_obj
->event
= event
;
765 IDOMEvent_AddRef(&event
->IDOMEvent_iface
);
767 init_dispex(&event_obj
->dispex
, (IUnknown
*)&event_obj
->IHTMLEventObj_iface
, &HTMLEventObj_dispex
);
771 HRESULT
create_event_obj(IHTMLEventObj
**ret
)
773 HTMLEventObj
*event_obj
;
775 event_obj
= alloc_event_obj(NULL
);
777 return E_OUTOFMEMORY
;
779 *ret
= &event_obj
->IHTMLEventObj_iface
;
783 static inline DOMEvent
*impl_from_IDOMEvent(IDOMEvent
*iface
)
785 return CONTAINING_RECORD(iface
, DOMEvent
, IDOMEvent_iface
);
788 static const IDOMEventVtbl DOMEventVtbl
;
790 static inline DOMEvent
*unsafe_impl_from_IDOMEvent(IDOMEvent
*iface
)
792 return iface
&& iface
->lpVtbl
== &DOMEventVtbl
? impl_from_IDOMEvent(iface
) : NULL
;
795 static HRESULT WINAPI
DOMEvent_QueryInterface(IDOMEvent
*iface
, REFIID riid
, void **ppv
)
797 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
799 TRACE("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
801 if(IsEqualGUID(&IID_IUnknown
, riid
))
802 *ppv
= &This
->IDOMEvent_iface
;
803 else if(IsEqualGUID(&IID_IDOMEvent
, riid
))
804 *ppv
= &This
->IDOMEvent_iface
;
805 else if(This
->ui_event
&& IsEqualGUID(&IID_IDOMUIEvent
, riid
))
806 *ppv
= &This
->IDOMUIEvent_iface
;
807 else if(This
->mouse_event
&& IsEqualGUID(&IID_IDOMMouseEvent
, riid
))
808 *ppv
= &This
->IDOMMouseEvent_iface
;
809 else if(This
->keyboard_event
&& IsEqualGUID(&IID_IDOMKeyboardEvent
, riid
))
810 *ppv
= &This
->IDOMKeyboardEvent_iface
;
811 else if(dispex_query_interface(&This
->dispex
, riid
, ppv
))
812 return *ppv
? S_OK
: E_NOINTERFACE
;
813 else if(!This
->query_interface
|| !(*ppv
= This
->query_interface(This
, riid
))) {
815 WARN("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
816 return E_NOINTERFACE
;
819 IUnknown_AddRef((IUnknown
*)*ppv
);
823 static ULONG WINAPI
DOMEvent_AddRef(IDOMEvent
*iface
)
825 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
826 LONG ref
= InterlockedIncrement(&This
->ref
);
828 TRACE("(%p) ref=%u\n", This
, ref
);
833 static ULONG WINAPI
DOMEvent_Release(IDOMEvent
*iface
)
835 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
836 LONG ref
= InterlockedDecrement(&This
->ref
);
838 TRACE("(%p) ref=%u\n", This
, ref
);
844 nsIDOMUIEvent_Release(This
->ui_event
);
845 if(This
->mouse_event
)
846 nsIDOMMouseEvent_Release(This
->mouse_event
);
847 if(This
->keyboard_event
)
848 nsIDOMKeyEvent_Release(This
->keyboard_event
);
850 IEventTarget_Release(&This
->target
->IEventTarget_iface
);
851 nsIDOMEvent_Release(This
->nsevent
);
852 release_dispex(&This
->dispex
);
853 heap_free(This
->type
);
860 static HRESULT WINAPI
DOMEvent_GetTypeInfoCount(IDOMEvent
*iface
, UINT
*pctinfo
)
862 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
863 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
866 static HRESULT WINAPI
DOMEvent_GetTypeInfo(IDOMEvent
*iface
, UINT iTInfo
,
867 LCID lcid
, ITypeInfo
**ppTInfo
)
869 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
870 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
873 static HRESULT WINAPI
DOMEvent_GetIDsOfNames(IDOMEvent
*iface
, REFIID riid
,
874 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
876 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
877 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
881 static HRESULT WINAPI
DOMEvent_Invoke(IDOMEvent
*iface
, DISPID dispIdMember
,
882 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
883 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
885 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
886 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
887 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
890 static HRESULT WINAPI
DOMEvent_get_bubbles(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
892 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
894 TRACE("(%p)->(%p)\n", This
, p
);
896 *p
= variant_bool(This
->bubbles
);
900 static HRESULT WINAPI
DOMEvent_get_cancelable(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
902 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
904 TRACE("(%p)->(%p)\n", This
, p
);
906 *p
= variant_bool(This
->cancelable
);
910 static HRESULT WINAPI
DOMEvent_get_currentTarget(IDOMEvent
*iface
, IEventTarget
**p
)
912 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
914 TRACE("(%p)->(%p)\n", This
, p
);
916 if(This
->current_target
)
917 IEventTarget_AddRef(*p
= &This
->current_target
->IEventTarget_iface
);
923 static HRESULT WINAPI
DOMEvent_get_defaultPrevented(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
925 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
927 TRACE("(%p)->(%p)\n", This
, p
);
929 *p
= variant_bool(This
->prevent_default
);
933 static HRESULT WINAPI
DOMEvent_get_eventPhase(IDOMEvent
*iface
, USHORT
*p
)
935 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
937 TRACE("(%p)->(%p)\n", This
, p
);
943 static HRESULT WINAPI
DOMEvent_get_target(IDOMEvent
*iface
, IEventTarget
**p
)
945 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
947 TRACE("(%p)->(%p)\n", This
, p
);
950 IEventTarget_AddRef(*p
= &This
->target
->IEventTarget_iface
);
956 static HRESULT WINAPI
DOMEvent_get_timeStamp(IDOMEvent
*iface
, ULONGLONG
*p
)
958 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
960 TRACE("(%p)->(%p)\n", This
, p
);
962 *p
= This
->time_stamp
;
966 static HRESULT WINAPI
DOMEvent_get_type(IDOMEvent
*iface
, BSTR
*p
)
968 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
970 TRACE("(%p)->(%p)\n", This
, p
);
973 *p
= SysAllocString(This
->type
);
975 return E_OUTOFMEMORY
;
983 #define nsIDOMEvent_InitEvent(_this,type,bubbles,cancelable) \
984 ((void (WINAPI*)(void*,nsIDOMEvent*,const nsAString*,cpp_bool,cpp_bool)) \
985 &call_thiscall_func)((_this)->lpVtbl->InitEvent,_this,type,bubbles,cancelable)
989 static HRESULT WINAPI
DOMEvent_initEvent(IDOMEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
, VARIANT_BOOL cancelable
)
991 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
994 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_w(type
), can_bubble
, cancelable
);
997 TRACE("called on already dispatched event\n");
1001 heap_free(This
->type
);
1002 This
->type
= heap_strdupW(type
);
1004 return E_OUTOFMEMORY
;
1005 This
->event_id
= str_to_eid(type
);
1007 This
->bubbles
= !!can_bubble
;
1008 This
->cancelable
= !!cancelable
;
1010 nsAString_InitDepend(&nsstr
, type
);
1011 nsIDOMEvent_InitEvent(This
->nsevent
, &nsstr
, This
->bubbles
, This
->cancelable
);
1012 nsAString_Finish(&nsstr
);
1017 static HRESULT WINAPI
DOMEvent_preventDefault(IDOMEvent
*iface
)
1019 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1021 TRACE("(%p)\n", This
);
1023 if(This
->current_target
&& This
->cancelable
) {
1024 This
->prevent_default
= TRUE
;
1025 nsIDOMEvent_PreventDefault(This
->nsevent
);
1030 static HRESULT WINAPI
DOMEvent_stopPropagation(IDOMEvent
*iface
)
1032 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1034 TRACE("(%p)\n", This
);
1036 This
->stop_propagation
= TRUE
;
1037 nsIDOMEvent_StopPropagation(This
->nsevent
);
1041 static HRESULT WINAPI
DOMEvent_stopImmediatePropagation(IDOMEvent
*iface
)
1043 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1045 TRACE("(%p)\n", This
);
1047 This
->stop_immediate_propagation
= This
->stop_propagation
= TRUE
;
1048 nsIDOMEvent_StopImmediatePropagation(This
->nsevent
);
1052 static HRESULT WINAPI
DOMEvent_get_isTrusted(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
1054 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1055 FIXME("(%p)->(%p)\n", This
, p
);
1059 static HRESULT WINAPI
DOMEvent_put_cancelBubble(IDOMEvent
*iface
, VARIANT_BOOL v
)
1061 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1062 FIXME("(%p)->(%x)\n", This
, v
);
1066 static HRESULT WINAPI
DOMEvent_get_cancelBubble(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
1068 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1069 FIXME("(%p)->(%p)\n", This
, p
);
1073 static HRESULT WINAPI
DOMEvent_get_srcElement(IDOMEvent
*iface
, IHTMLElement
**p
)
1075 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1077 TRACE("(%p)->(%p)\n", This
, p
);
1080 IDispatchEx_QueryInterface(&This
->target
->dispex
.IDispatchEx_iface
, &IID_IHTMLElement
, (void**)p
);
1086 static const IDOMEventVtbl DOMEventVtbl
= {
1087 DOMEvent_QueryInterface
,
1090 DOMEvent_GetTypeInfoCount
,
1091 DOMEvent_GetTypeInfo
,
1092 DOMEvent_GetIDsOfNames
,
1094 DOMEvent_get_bubbles
,
1095 DOMEvent_get_cancelable
,
1096 DOMEvent_get_currentTarget
,
1097 DOMEvent_get_defaultPrevented
,
1098 DOMEvent_get_eventPhase
,
1099 DOMEvent_get_target
,
1100 DOMEvent_get_timeStamp
,
1103 DOMEvent_preventDefault
,
1104 DOMEvent_stopPropagation
,
1105 DOMEvent_stopImmediatePropagation
,
1106 DOMEvent_get_isTrusted
,
1107 DOMEvent_put_cancelBubble
,
1108 DOMEvent_get_cancelBubble
,
1109 DOMEvent_get_srcElement
1112 static inline DOMEvent
*impl_from_IDOMUIEvent(IDOMUIEvent
*iface
)
1114 return CONTAINING_RECORD(iface
, DOMEvent
, IDOMUIEvent_iface
);
1117 static HRESULT WINAPI
DOMUIEvent_QueryInterface(IDOMUIEvent
*iface
, REFIID riid
, void **ppv
)
1119 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1120 return IDOMEvent_QueryInterface(&This
->IDOMEvent_iface
, riid
, ppv
);
1123 static ULONG WINAPI
DOMUIEvent_AddRef(IDOMUIEvent
*iface
)
1125 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1126 return IDOMEvent_AddRef(&This
->IDOMEvent_iface
);
1129 static ULONG WINAPI
DOMUIEvent_Release(IDOMUIEvent
*iface
)
1131 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1132 return IDOMEvent_Release(&This
->IDOMEvent_iface
);
1135 static HRESULT WINAPI
DOMUIEvent_GetTypeInfoCount(IDOMUIEvent
*iface
, UINT
*pctinfo
)
1137 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1138 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
1141 static HRESULT WINAPI
DOMUIEvent_GetTypeInfo(IDOMUIEvent
*iface
, UINT iTInfo
,
1142 LCID lcid
, ITypeInfo
**ppTInfo
)
1144 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1145 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1148 static HRESULT WINAPI
DOMUIEvent_GetIDsOfNames(IDOMUIEvent
*iface
, REFIID riid
,
1149 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1151 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1152 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1156 static HRESULT WINAPI
DOMUIEvent_Invoke(IDOMUIEvent
*iface
, DISPID dispIdMember
,
1157 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1158 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1160 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1161 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1162 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1165 static HRESULT WINAPI
DOMUIEvent_get_view(IDOMUIEvent
*iface
, IHTMLWindow2
**p
)
1167 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1168 mozIDOMWindowProxy
*moz_window
;
1169 HTMLOuterWindow
*view
= NULL
;
1172 TRACE("(%p)->(%p)\n", This
, p
);
1174 nsres
= nsIDOMUIEvent_GetView(This
->ui_event
, &moz_window
);
1175 if(NS_FAILED(nsres
))
1179 view
= mozwindow_to_window(moz_window
);
1180 mozIDOMWindowProxy_Release(moz_window
);
1183 IHTMLWindow2_AddRef((*p
= &view
->base
.inner_window
->base
.IHTMLWindow2_iface
));
1189 static HRESULT WINAPI
DOMUIEvent_get_detail(IDOMUIEvent
*iface
, LONG
*p
)
1191 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1195 TRACE("(%p)->(%p)\n", This
, p
);
1197 nsres
= nsIDOMUIEvent_GetDetail(This
->ui_event
, &detail
);
1198 if(NS_FAILED(nsres
))
1205 static HRESULT WINAPI
DOMUIEvent_initUIEvent(IDOMUIEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
1206 VARIANT_BOOL cancelable
, IHTMLWindow2
*view
, LONG detail
)
1208 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1213 TRACE("(%p)->(%s %x %x %p %x)\n", This
, debugstr_w(type
), can_bubble
, cancelable
, view
, detail
);
1216 TRACE("called on already dispatched event\n");
1221 FIXME("view argument is not supported\n");
1223 hres
= IDOMEvent_initEvent(&This
->IDOMEvent_iface
, type
, can_bubble
, cancelable
);
1227 nsAString_InitDepend(&type_str
, type
);
1228 nsres
= nsIDOMUIEvent_InitUIEvent(This
->ui_event
, &type_str
, !!can_bubble
, !!cancelable
,
1229 NULL
/* FIXME */, detail
);
1230 nsAString_Finish(&type_str
);
1231 if(NS_FAILED(nsres
)) {
1232 FIXME("InitUIEvent failed: %08x\n", nsres
);
1239 static const IDOMUIEventVtbl DOMUIEventVtbl
= {
1240 DOMUIEvent_QueryInterface
,
1243 DOMUIEvent_GetTypeInfoCount
,
1244 DOMUIEvent_GetTypeInfo
,
1245 DOMUIEvent_GetIDsOfNames
,
1247 DOMUIEvent_get_view
,
1248 DOMUIEvent_get_detail
,
1249 DOMUIEvent_initUIEvent
1252 static inline DOMEvent
*impl_from_IDOMMouseEvent(IDOMMouseEvent
*iface
)
1254 return CONTAINING_RECORD(iface
, DOMEvent
, IDOMMouseEvent_iface
);
1257 static HRESULT WINAPI
DOMMouseEvent_QueryInterface(IDOMMouseEvent
*iface
, REFIID riid
, void **ppv
)
1259 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1260 return IDOMEvent_QueryInterface(&This
->IDOMEvent_iface
, riid
, ppv
);
1263 static ULONG WINAPI
DOMMouseEvent_AddRef(IDOMMouseEvent
*iface
)
1265 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1266 return IDOMEvent_AddRef(&This
->IDOMEvent_iface
);
1269 static ULONG WINAPI
DOMMouseEvent_Release(IDOMMouseEvent
*iface
)
1271 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1272 return IDOMEvent_Release(&This
->IDOMEvent_iface
);
1275 static HRESULT WINAPI
DOMMouseEvent_GetTypeInfoCount(IDOMMouseEvent
*iface
, UINT
*pctinfo
)
1277 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1278 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
1281 static HRESULT WINAPI
DOMMouseEvent_GetTypeInfo(IDOMMouseEvent
*iface
, UINT iTInfo
,
1282 LCID lcid
, ITypeInfo
**ppTInfo
)
1284 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1285 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1288 static HRESULT WINAPI
DOMMouseEvent_GetIDsOfNames(IDOMMouseEvent
*iface
, REFIID riid
,
1289 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1291 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1292 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1296 static HRESULT WINAPI
DOMMouseEvent_Invoke(IDOMMouseEvent
*iface
, DISPID dispIdMember
,
1297 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1298 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1300 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1301 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1302 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1305 static HRESULT WINAPI
DOMMouseEvent_get_screenX(IDOMMouseEvent
*iface
, LONG
*p
)
1307 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1311 TRACE("(%p)->(%p)\n", This
, p
);
1313 nsres
= nsIDOMMouseEvent_GetScreenX(This
->mouse_event
, &screen_x
);
1314 if(NS_FAILED(nsres
))
1321 static HRESULT WINAPI
DOMMouseEvent_get_screenY(IDOMMouseEvent
*iface
, LONG
*p
)
1323 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1327 TRACE("(%p)->(%p)\n", This
, p
);
1329 nsres
= nsIDOMMouseEvent_GetScreenY(This
->mouse_event
, &screen_y
);
1330 if(NS_FAILED(nsres
))
1337 static HRESULT WINAPI
DOMMouseEvent_get_clientX(IDOMMouseEvent
*iface
, LONG
*p
)
1339 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1343 TRACE("(%p)->(%p)\n", This
, p
);
1345 nsres
= nsIDOMMouseEvent_GetClientX(This
->mouse_event
, &client_x
);
1346 if(NS_FAILED(nsres
))
1353 static HRESULT WINAPI
DOMMouseEvent_get_clientY(IDOMMouseEvent
*iface
, LONG
*p
)
1355 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1359 TRACE("(%p)->(%p)\n", This
, p
);
1361 nsres
= nsIDOMMouseEvent_GetClientY(This
->mouse_event
, &client_y
);
1362 if(NS_FAILED(nsres
))
1369 static HRESULT WINAPI
DOMMouseEvent_get_ctrlKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1371 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1375 TRACE("(%p)->(%p)\n", This
, p
);
1377 nsres
= nsIDOMMouseEvent_GetCtrlKey(This
->mouse_event
, &r
);
1378 if(NS_FAILED(nsres
))
1381 *p
= variant_bool(r
);
1385 static HRESULT WINAPI
DOMMouseEvent_get_shiftKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1387 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1391 TRACE("(%p)->(%p)\n", This
, p
);
1393 nsres
= nsIDOMMouseEvent_GetShiftKey(This
->mouse_event
, &r
);
1394 if(NS_FAILED(nsres
))
1397 *p
= variant_bool(r
);
1401 static HRESULT WINAPI
DOMMouseEvent_get_altKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1403 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1407 TRACE("(%p)->(%p)\n", This
, p
);
1409 nsres
= nsIDOMMouseEvent_GetAltKey(This
->mouse_event
, &r
);
1410 if(NS_FAILED(nsres
))
1413 *p
= variant_bool(r
);
1417 static HRESULT WINAPI
DOMMouseEvent_get_metaKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1419 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1423 TRACE("(%p)->(%p)\n", This
, p
);
1425 nsres
= nsIDOMMouseEvent_GetMetaKey(This
->mouse_event
, &r
);
1426 if(NS_FAILED(nsres
))
1429 *p
= variant_bool(r
);
1433 static HRESULT WINAPI
DOMMouseEvent_get_button(IDOMMouseEvent
*iface
, USHORT
*p
)
1435 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1439 TRACE("(%p)->(%p)\n", This
, p
);
1441 nsres
= nsIDOMMouseEvent_GetButton(This
->mouse_event
, &r
);
1442 if(NS_FAILED(nsres
))
1449 static HRESULT WINAPI
DOMMouseEvent_get_relatedTarget(IDOMMouseEvent
*iface
, IEventTarget
**p
)
1451 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1452 nsIDOMEventTarget
*related_target
;
1453 nsIDOMNode
*target_node
;
1458 TRACE("(%p)->(%p)\n", This
, p
);
1460 nsres
= nsIDOMMouseEvent_GetRelatedTarget(This
->mouse_event
, &related_target
);
1461 if(NS_FAILED(nsres
))
1464 if(!related_target
) {
1469 nsres
= nsIDOMEventTarget_QueryInterface(related_target
, &IID_nsIDOMNode
, (void**)&target_node
);
1470 nsIDOMEventTarget_Release(related_target
);
1471 if(NS_FAILED(nsres
)) {
1472 FIXME("Only node targets supported\n");
1476 hres
= get_node(target_node
, TRUE
, &node
);
1477 nsIDOMNode_Release(target_node
);
1481 *p
= &node
->event_target
.IEventTarget_iface
;
1485 static HRESULT WINAPI
DOMMouseEvent_initMouseEvent(IDOMMouseEvent
*iface
, BSTR type
,
1486 VARIANT_BOOL can_bubble
, VARIANT_BOOL cancelable
, IHTMLWindow2
*view
, LONG detail
,
1487 LONG screen_x
, LONG screen_y
, LONG client_x
, LONG client_y
, VARIANT_BOOL ctrl_key
,
1488 VARIANT_BOOL alt_key
, VARIANT_BOOL shift_key
, VARIANT_BOOL meta_key
, USHORT button
,
1489 IEventTarget
*related_target
)
1491 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1492 nsIDOMEventTarget
*nstarget
= NULL
;
1497 TRACE("(%p)->(%s %x %x %p %d %d %d %d %d %x %x %x %x %u %p)\n", This
, debugstr_w(type
),
1498 can_bubble
, cancelable
, view
, detail
, screen_x
, screen_y
, client_x
, client_y
,
1499 ctrl_key
, alt_key
, shift_key
, meta_key
, button
, related_target
);
1502 TRACE("called on already dispatched event\n");
1507 FIXME("view argument is not supported\n");
1509 if(related_target
) {
1510 hres
= get_gecko_target(related_target
, &nstarget
);
1515 hres
= IDOMEvent_initEvent(&This
->IDOMEvent_iface
, type
, can_bubble
, cancelable
);
1516 if(SUCCEEDED(hres
)) {
1517 nsAString_InitDepend(&type_str
, type
);
1518 nsres
= nsIDOMMouseEvent_InitMouseEvent(This
->mouse_event
, &type_str
, can_bubble
, cancelable
,
1519 NULL
/* FIXME */, detail
, screen_x
, screen_y
,
1520 client_x
, client_y
, !!ctrl_key
, !!alt_key
, !!shift_key
,
1521 !!meta_key
, button
, nstarget
);
1522 nsAString_Finish(&type_str
);
1523 if(NS_FAILED(nsres
)) {
1524 FIXME("InitMouseEvent failed: %08x\n", nsres
);
1530 nsIDOMEventTarget_Release(nstarget
);
1534 static HRESULT WINAPI
DOMMouseEvent_getModifierState(IDOMMouseEvent
*iface
, BSTR key
,
1535 VARIANT_BOOL
*activated
)
1537 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1538 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(key
), activated
);
1542 static HRESULT WINAPI
DOMMouseEvent_get_buttons(IDOMMouseEvent
*iface
, USHORT
*p
)
1544 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1548 TRACE("(%p)->(%p)\n", This
, p
);
1550 nsres
= nsIDOMMouseEvent_GetButtons(This
->mouse_event
, &r
);
1551 if(NS_FAILED(nsres
))
1558 static HRESULT WINAPI
DOMMouseEvent_get_fromElement(IDOMMouseEvent
*iface
, IHTMLElement
**p
)
1560 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1561 IEventTarget
*related_target
= NULL
;
1563 TRACE("(%p)->(%p)\n", This
, p
);
1565 if(This
->event_id
!= EVENTID_LAST
) {
1566 HRESULT hres
= S_OK
;
1567 if(event_info
[This
->event_id
].flags
& EVENT_MOUSE_FROM_RELATED
)
1568 hres
= IDOMMouseEvent_get_relatedTarget(&This
->IDOMMouseEvent_iface
, &related_target
);
1569 else if(event_info
[This
->event_id
].flags
& EVENT_MOUSE_TO_RELATED
)
1570 hres
= IDOMEvent_get_target(&This
->IDOMEvent_iface
, &related_target
);
1575 if(!related_target
) {
1580 IEventTarget_QueryInterface(related_target
, &IID_IHTMLElement
, (void**)p
);
1584 static HRESULT WINAPI
DOMMouseEvent_get_toElement(IDOMMouseEvent
*iface
, IHTMLElement
**p
)
1586 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1587 IEventTarget
*related_target
= NULL
;
1589 TRACE("(%p)->(%p)\n", This
, p
);
1591 if(This
->event_id
!= EVENTID_LAST
) {
1592 HRESULT hres
= S_OK
;
1593 if(event_info
[This
->event_id
].flags
& EVENT_MOUSE_TO_RELATED
)
1594 hres
= IDOMMouseEvent_get_relatedTarget(&This
->IDOMMouseEvent_iface
, &related_target
);
1595 else if(event_info
[This
->event_id
].flags
& EVENT_MOUSE_FROM_RELATED
)
1596 hres
= IDOMEvent_get_target(&This
->IDOMEvent_iface
, &related_target
);
1601 if(!related_target
) {
1606 IEventTarget_QueryInterface(related_target
, &IID_IHTMLElement
, (void**)p
);
1610 static HRESULT WINAPI
DOMMouseEvent_get_x(IDOMMouseEvent
*iface
, LONG
*p
)
1612 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1613 FIXME("(%p)->(%p)\n", This
, p
);
1617 static HRESULT WINAPI
DOMMouseEvent_get_y(IDOMMouseEvent
*iface
, LONG
*p
)
1619 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1620 FIXME("(%p)->(%p)\n", This
, p
);
1624 static HRESULT WINAPI
DOMMouseEvent_get_offsetX(IDOMMouseEvent
*iface
, LONG
*p
)
1626 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1628 FIXME("(%p)->(%p) returning 0\n", This
, p
);
1634 static HRESULT WINAPI
DOMMouseEvent_get_offsetY(IDOMMouseEvent
*iface
, LONG
*p
)
1636 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1638 FIXME("(%p)->(%p) returning 0\n", This
, p
);
1644 static HRESULT WINAPI
DOMMouseEvent_get_pageX(IDOMMouseEvent
*iface
, LONG
*p
)
1646 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1650 TRACE("(%p)->(%p)\n", This
, p
);
1652 nsres
= nsIDOMMouseEvent_GetPageX(This
->mouse_event
, &r
);
1653 if(NS_FAILED(nsres
))
1660 static HRESULT WINAPI
DOMMouseEvent_get_pageY(IDOMMouseEvent
*iface
, LONG
*p
)
1662 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1666 TRACE("(%p)->(%p)\n", This
, p
);
1668 nsres
= nsIDOMMouseEvent_GetPageY(This
->mouse_event
, &r
);
1669 if(NS_FAILED(nsres
))
1676 static HRESULT WINAPI
DOMMouseEvent_get_layerX(IDOMMouseEvent
*iface
, LONG
*p
)
1678 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1679 FIXME("(%p)->(%p)\n", This
, p
);
1683 static HRESULT WINAPI
DOMMouseEvent_get_layerY(IDOMMouseEvent
*iface
, LONG
*p
)
1685 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1686 FIXME("(%p)->(%p)\n", This
, p
);
1690 static HRESULT WINAPI
DOMMouseEvent_get_which(IDOMMouseEvent
*iface
, USHORT
*p
)
1692 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1696 TRACE("(%p)->(%p)\n", This
, p
);
1698 nsres
= nsIDOMMouseEvent_GetWhich(This
->mouse_event
, &r
);
1699 if(NS_FAILED(nsres
))
1706 static const IDOMMouseEventVtbl DOMMouseEventVtbl
= {
1707 DOMMouseEvent_QueryInterface
,
1708 DOMMouseEvent_AddRef
,
1709 DOMMouseEvent_Release
,
1710 DOMMouseEvent_GetTypeInfoCount
,
1711 DOMMouseEvent_GetTypeInfo
,
1712 DOMMouseEvent_GetIDsOfNames
,
1713 DOMMouseEvent_Invoke
,
1714 DOMMouseEvent_get_screenX
,
1715 DOMMouseEvent_get_screenY
,
1716 DOMMouseEvent_get_clientX
,
1717 DOMMouseEvent_get_clientY
,
1718 DOMMouseEvent_get_ctrlKey
,
1719 DOMMouseEvent_get_shiftKey
,
1720 DOMMouseEvent_get_altKey
,
1721 DOMMouseEvent_get_metaKey
,
1722 DOMMouseEvent_get_button
,
1723 DOMMouseEvent_get_relatedTarget
,
1724 DOMMouseEvent_initMouseEvent
,
1725 DOMMouseEvent_getModifierState
,
1726 DOMMouseEvent_get_buttons
,
1727 DOMMouseEvent_get_fromElement
,
1728 DOMMouseEvent_get_toElement
,
1729 DOMMouseEvent_get_x
,
1730 DOMMouseEvent_get_y
,
1731 DOMMouseEvent_get_offsetX
,
1732 DOMMouseEvent_get_offsetY
,
1733 DOMMouseEvent_get_pageX
,
1734 DOMMouseEvent_get_pageY
,
1735 DOMMouseEvent_get_layerX
,
1736 DOMMouseEvent_get_layerY
,
1737 DOMMouseEvent_get_which
1740 static inline DOMEvent
*impl_from_IDOMKeyboardEvent(IDOMKeyboardEvent
*iface
)
1742 return CONTAINING_RECORD(iface
, DOMEvent
, IDOMKeyboardEvent_iface
);
1745 static HRESULT WINAPI
DOMKeyboardEvent_QueryInterface(IDOMKeyboardEvent
*iface
, REFIID riid
, void **ppv
)
1747 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1748 return IDOMEvent_QueryInterface(&This
->IDOMEvent_iface
, riid
, ppv
);
1751 static ULONG WINAPI
DOMKeyboardEvent_AddRef(IDOMKeyboardEvent
*iface
)
1753 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1754 return IDOMEvent_AddRef(&This
->IDOMEvent_iface
);
1757 static ULONG WINAPI
DOMKeyboardEvent_Release(IDOMKeyboardEvent
*iface
)
1759 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1760 return IDOMEvent_Release(&This
->IDOMEvent_iface
);
1763 static HRESULT WINAPI
DOMKeyboardEvent_GetTypeInfoCount(IDOMKeyboardEvent
*iface
, UINT
*pctinfo
)
1765 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1766 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
1769 static HRESULT WINAPI
DOMKeyboardEvent_GetTypeInfo(IDOMKeyboardEvent
*iface
, UINT iTInfo
,
1770 LCID lcid
, ITypeInfo
**ppTInfo
)
1772 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1773 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1776 static HRESULT WINAPI
DOMKeyboardEvent_GetIDsOfNames(IDOMKeyboardEvent
*iface
, REFIID riid
,
1777 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1779 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1780 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1784 static HRESULT WINAPI
DOMKeyboardEvent_Invoke(IDOMKeyboardEvent
*iface
, DISPID dispIdMember
,
1785 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1786 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1788 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1789 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1790 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1793 static HRESULT WINAPI
DOMKeyboardEvent_get_key(IDOMKeyboardEvent
*iface
, BSTR
*p
)
1795 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1799 TRACE("(%p)->(%p)\n", This
, p
);
1802 nsAString_Init(&key_str
, NULL
);
1803 nsres
= nsIDOMKeyEvent_GetKey(This
->keyboard_event
, &key_str
);
1804 return return_nsstr(nsres
, &key_str
, p
);
1807 static HRESULT WINAPI
DOMKeyboardEvent_get_location(IDOMKeyboardEvent
*iface
, ULONG
*p
)
1809 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1813 TRACE("(%p)->(%p)\n", This
, p
);
1815 nsres
= nsIDOMKeyEvent_GetLocation(This
->keyboard_event
, &r
);
1816 if(NS_FAILED(nsres
))
1823 static HRESULT WINAPI
DOMKeyboardEvent_get_ctrlKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1825 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1829 TRACE("(%p)->(%p)\n", This
, p
);
1831 nsres
= nsIDOMKeyEvent_GetCtrlKey(This
->keyboard_event
, &r
);
1832 if(NS_FAILED(nsres
))
1835 *p
= variant_bool(r
);
1839 static HRESULT WINAPI
DOMKeyboardEvent_get_shiftKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1841 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1845 TRACE("(%p)->(%p)\n", This
, p
);
1847 nsres
= nsIDOMKeyEvent_GetShiftKey(This
->keyboard_event
, &r
);
1848 if(NS_FAILED(nsres
))
1851 *p
= variant_bool(r
);
1855 static HRESULT WINAPI
DOMKeyboardEvent_get_altKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1857 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1861 TRACE("(%p)->(%p)\n", This
, p
);
1863 nsres
= nsIDOMKeyEvent_GetAltKey(This
->keyboard_event
, &r
);
1864 if(NS_FAILED(nsres
))
1867 *p
= variant_bool(r
);
1871 static HRESULT WINAPI
DOMKeyboardEvent_get_metaKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1873 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1877 TRACE("(%p)->(%p)\n", This
, p
);
1879 nsres
= nsIDOMKeyEvent_GetMetaKey(This
->keyboard_event
, &r
);
1880 if(NS_FAILED(nsres
))
1883 *p
= variant_bool(r
);
1887 static HRESULT WINAPI
DOMKeyboardEvent_get_repeat(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1889 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1893 TRACE("(%p)->(%p)\n", This
, p
);
1895 nsres
= nsIDOMKeyEvent_GetRepeat(This
->keyboard_event
, &r
);
1896 if(NS_FAILED(nsres
))
1899 *p
= variant_bool(r
);
1903 static HRESULT WINAPI
DOMKeyboardEvent_getModifierState(IDOMKeyboardEvent
*iface
, BSTR key
,
1904 VARIANT_BOOL
*state
)
1906 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1907 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(key
), state
);
1911 static HRESULT WINAPI
DOMKeyboardEvent_initKeyboardEvent(IDOMKeyboardEvent
*iface
, BSTR type
,
1912 VARIANT_BOOL can_bubble
, VARIANT_BOOL cancelable
, IHTMLWindow2
*view
, BSTR key
,
1913 ULONG location
, BSTR modifiers_list
, VARIANT_BOOL repeat
, BSTR locale
)
1915 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1916 FIXME("(%p)->(%s %x %x %p %s %u %s %x %s)\n", This
, debugstr_w(type
), can_bubble
,
1917 cancelable
, view
, debugstr_w(key
), location
, debugstr_w(modifiers_list
),
1918 repeat
, debugstr_w(locale
));
1922 static HRESULT WINAPI
DOMKeyboardEvent_get_keyCode(IDOMKeyboardEvent
*iface
, LONG
*p
)
1924 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1928 TRACE("(%p)->(%p)\n", This
, p
);
1930 nsres
= nsIDOMKeyEvent_GetKeyCode(This
->keyboard_event
, &r
);
1931 if(NS_FAILED(nsres
))
1938 static HRESULT WINAPI
DOMKeyboardEvent_get_charCode(IDOMKeyboardEvent
*iface
, LONG
*p
)
1940 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1944 TRACE("(%p)->(%p)\n", This
, p
);
1946 nsres
= nsIDOMKeyEvent_GetKeyCode(This
->keyboard_event
, &r
);
1947 if(NS_FAILED(nsres
))
1954 static HRESULT WINAPI
DOMKeyboardEvent_get_which(IDOMKeyboardEvent
*iface
, LONG
*p
)
1956 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1960 TRACE("(%p)->(%p)\n", This
, p
);
1962 nsres
= nsIDOMKeyEvent_GetWhich(This
->keyboard_event
, &r
);
1963 if(NS_FAILED(nsres
))
1970 static HRESULT WINAPI
DOMKeyboardEvent_get_char(IDOMKeyboardEvent
*iface
, VARIANT
*p
)
1972 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1973 FIXME("(%p)->(%p)\n", This
, p
);
1977 static HRESULT WINAPI
DOMKeyboardEvent_get_locale(IDOMKeyboardEvent
*iface
, BSTR
*p
)
1979 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1980 FIXME("(%p)->(%p)\n", This
, p
);
1984 static const IDOMKeyboardEventVtbl DOMKeyboardEventVtbl
= {
1985 DOMKeyboardEvent_QueryInterface
,
1986 DOMKeyboardEvent_AddRef
,
1987 DOMKeyboardEvent_Release
,
1988 DOMKeyboardEvent_GetTypeInfoCount
,
1989 DOMKeyboardEvent_GetTypeInfo
,
1990 DOMKeyboardEvent_GetIDsOfNames
,
1991 DOMKeyboardEvent_Invoke
,
1992 DOMKeyboardEvent_get_key
,
1993 DOMKeyboardEvent_get_location
,
1994 DOMKeyboardEvent_get_ctrlKey
,
1995 DOMKeyboardEvent_get_shiftKey
,
1996 DOMKeyboardEvent_get_altKey
,
1997 DOMKeyboardEvent_get_metaKey
,
1998 DOMKeyboardEvent_get_repeat
,
1999 DOMKeyboardEvent_getModifierState
,
2000 DOMKeyboardEvent_initKeyboardEvent
,
2001 DOMKeyboardEvent_get_keyCode
,
2002 DOMKeyboardEvent_get_charCode
,
2003 DOMKeyboardEvent_get_which
,
2004 DOMKeyboardEvent_get_char
,
2005 DOMKeyboardEvent_get_locale
2010 IDOMCustomEvent IDOMCustomEvent_iface
;
2014 static inline DOMCustomEvent
*impl_from_IDOMCustomEvent(IDOMCustomEvent
*iface
)
2016 return CONTAINING_RECORD(iface
, DOMCustomEvent
, IDOMCustomEvent_iface
);
2019 static HRESULT WINAPI
DOMCustomEvent_QueryInterface(IDOMCustomEvent
*iface
, REFIID riid
, void **ppv
)
2021 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2022 return IDOMEvent_QueryInterface(&This
->event
.IDOMEvent_iface
, riid
, ppv
);
2025 static ULONG WINAPI
DOMCustomEvent_AddRef(IDOMCustomEvent
*iface
)
2027 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2028 return IDOMEvent_AddRef(&This
->event
.IDOMEvent_iface
);
2031 static ULONG WINAPI
DOMCustomEvent_Release(IDOMCustomEvent
*iface
)
2033 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2034 return IDOMEvent_Release(&This
->event
.IDOMEvent_iface
);
2037 static HRESULT WINAPI
DOMCustomEvent_GetTypeInfoCount(IDOMCustomEvent
*iface
, UINT
*pctinfo
)
2039 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2040 return IDispatchEx_GetTypeInfoCount(&This
->event
.dispex
.IDispatchEx_iface
, pctinfo
);
2043 static HRESULT WINAPI
DOMCustomEvent_GetTypeInfo(IDOMCustomEvent
*iface
, UINT iTInfo
,
2044 LCID lcid
, ITypeInfo
**ppTInfo
)
2046 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2047 return IDispatchEx_GetTypeInfo(&This
->event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
2050 static HRESULT WINAPI
DOMCustomEvent_GetIDsOfNames(IDOMCustomEvent
*iface
, REFIID riid
,
2051 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2053 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2054 return IDispatchEx_GetIDsOfNames(&This
->event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
2058 static HRESULT WINAPI
DOMCustomEvent_Invoke(IDOMCustomEvent
*iface
, DISPID dispIdMember
,
2059 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2060 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2062 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2063 return IDispatchEx_Invoke(&This
->event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
2064 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2067 static HRESULT WINAPI
DOMCustomEvent_get_detail(IDOMCustomEvent
*iface
, VARIANT
*p
)
2069 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2071 TRACE("(%p)->(%p)\n", This
, p
);
2074 return VariantCopy(p
, &This
->detail
);
2077 static HRESULT WINAPI
DOMCustomEvent_initCustomEvent(IDOMCustomEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
2078 VARIANT_BOOL cancelable
, VARIANT
*detail
)
2080 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2083 TRACE("(%p)->(%s %x %x %s)\n", This
, debugstr_w(type
), can_bubble
, cancelable
, debugstr_variant(detail
));
2085 hres
= IDOMEvent_initEvent(&This
->event
.IDOMEvent_iface
, type
, can_bubble
, cancelable
);
2089 return VariantCopy(&This
->detail
, detail
);
2092 static const IDOMCustomEventVtbl DOMCustomEventVtbl
= {
2093 DOMCustomEvent_QueryInterface
,
2094 DOMCustomEvent_AddRef
,
2095 DOMCustomEvent_Release
,
2096 DOMCustomEvent_GetTypeInfoCount
,
2097 DOMCustomEvent_GetTypeInfo
,
2098 DOMCustomEvent_GetIDsOfNames
,
2099 DOMCustomEvent_Invoke
,
2100 DOMCustomEvent_get_detail
,
2101 DOMCustomEvent_initCustomEvent
2104 static DOMCustomEvent
*DOMCustomEvent_from_DOMEvent(DOMEvent
*event
)
2106 return CONTAINING_RECORD(event
, DOMCustomEvent
, event
);
2109 static void *DOMCustomEvent_query_interface(DOMEvent
*event
, REFIID riid
)
2111 DOMCustomEvent
*custom_event
= DOMCustomEvent_from_DOMEvent(event
);
2112 if(IsEqualGUID(&IID_IDOMCustomEvent
, riid
))
2113 return &custom_event
->IDOMCustomEvent_iface
;
2117 static void DOMCustomEvent_destroy(DOMEvent
*event
)
2119 DOMCustomEvent
*custom_event
= DOMCustomEvent_from_DOMEvent(event
);
2120 VariantClear(&custom_event
->detail
);
2124 static const tid_t DOMEvent_iface_tids
[] = {
2129 static dispex_static_data_t DOMEvent_dispex
= {
2135 static const tid_t DOMUIEvent_iface_tids
[] = {
2141 static dispex_static_data_t DOMUIEvent_dispex
= {
2144 DOMUIEvent_iface_tids
2147 static const tid_t DOMMouseEvent_iface_tids
[] = {
2154 static dispex_static_data_t DOMMouseEvent_dispex
= {
2156 DispDOMMouseEvent_tid
,
2157 DOMMouseEvent_iface_tids
2160 static const tid_t DOMKeyboardEvent_iface_tids
[] = {
2163 IDOMKeyboardEvent_tid
,
2167 static dispex_static_data_t DOMKeyboardEvent_dispex
= {
2169 DispDOMKeyboardEvent_tid
,
2170 DOMKeyboardEvent_iface_tids
2173 static const tid_t DOMCustomEvent_iface_tids
[] = {
2175 IDOMCustomEvent_tid
,
2179 static dispex_static_data_t DOMCustomEvent_dispex
= {
2181 DispDOMCustomEvent_tid
,
2182 DOMCustomEvent_iface_tids
2185 static BOOL
check_event_iface(nsIDOMEvent
*event
, REFIID riid
)
2190 nsres
= nsIDOMEvent_QueryInterface(event
, riid
, (void**)&iface
);
2191 if(NS_FAILED(nsres
))
2194 nsISupports_Release(iface
);
2198 static DOMEvent
*alloc_event(nsIDOMEvent
*nsevent
, eventid_t event_id
)
2200 dispex_static_data_t
*dispex_data
= &DOMEvent_dispex
;
2201 DOMEvent
*event
= NULL
;
2205 /* 1601 to 1970 is 369 years plus 89 leap days */
2206 const ULONGLONG time_epoch
= (ULONGLONG
)(369 * 365 + 89) * 86400 * 1000;
2208 if(check_event_iface(nsevent
, &IID_nsIDOMCustomEvent
)) {
2209 DOMCustomEvent
*custom_event
= heap_alloc_zero(sizeof(*custom_event
));
2213 custom_event
->IDOMCustomEvent_iface
.lpVtbl
= &DOMCustomEventVtbl
;
2214 custom_event
->event
.query_interface
= DOMCustomEvent_query_interface
;
2215 custom_event
->event
.destroy
= DOMCustomEvent_destroy
;
2216 event
= &custom_event
->event
;
2217 dispex_data
= &DOMCustomEvent_dispex
;
2219 event
= heap_alloc_zero(sizeof(*event
));
2224 event
->IDOMEvent_iface
.lpVtbl
= &DOMEventVtbl
;
2225 event
->IDOMUIEvent_iface
.lpVtbl
= &DOMUIEventVtbl
;
2226 event
->IDOMMouseEvent_iface
.lpVtbl
= &DOMMouseEventVtbl
;
2227 event
->IDOMKeyboardEvent_iface
.lpVtbl
= &DOMKeyboardEventVtbl
;
2229 event
->event_id
= event_id
;
2230 if(event_id
!= EVENTID_LAST
) {
2231 event
->type
= heap_strdupW(event_info
[event_id
].name
);
2236 event
->bubbles
= (event_info
[event_id
].flags
& EVENT_BUBBLES
) != 0;
2237 event
->cancelable
= (event_info
[event_id
].flags
& EVENT_CANCELABLE
) != 0;
2239 nsIDOMEvent_AddRef(event
->nsevent
= nsevent
);
2241 GetSystemTimeAsFileTime(&time
);
2242 event
->time_stamp
= (((ULONGLONG
)time
.dwHighDateTime
<<32) + time
.dwLowDateTime
) / 10000
2245 nsres
= nsIDOMEvent_QueryInterface(nsevent
, &IID_nsIDOMUIEvent
, (void**)&event
->ui_event
);
2246 if(NS_SUCCEEDED(nsres
))
2247 dispex_data
= &DOMUIEvent_dispex
;
2249 event
->ui_event
= NULL
;
2251 nsres
= nsIDOMEvent_QueryInterface(nsevent
, &IID_nsIDOMMouseEvent
, (void**)&event
->mouse_event
);
2252 if(NS_SUCCEEDED(nsres
))
2253 dispex_data
= &DOMMouseEvent_dispex
;
2255 event
->mouse_event
= NULL
;
2257 nsres
= nsIDOMEvent_QueryInterface(nsevent
, &IID_nsIDOMKeyEvent
, (void**)&event
->keyboard_event
);
2258 if(NS_SUCCEEDED(nsres
))
2259 dispex_data
= &DOMKeyboardEvent_dispex
;
2261 event
->keyboard_event
= NULL
;
2263 init_dispex(&event
->dispex
, (IUnknown
*)&event
->IDOMEvent_iface
, dispex_data
);
2267 HRESULT
create_event_from_nsevent(nsIDOMEvent
*nsevent
, DOMEvent
**ret_event
)
2269 eventid_t event_id
= EVENTID_LAST
;
2274 nsAString_Init(&nsstr
, NULL
);
2275 nsres
= nsIDOMEvent_GetType(nsevent
, &nsstr
);
2276 if(NS_SUCCEEDED(nsres
)) {
2278 nsAString_GetData(&nsstr
, &type
);
2279 event_id
= str_to_eid(type
);
2280 if(event_id
== EVENTID_LAST
)
2281 FIXME("unknown event type %s\n", debugstr_w(type
));
2283 ERR("GetType failed: %08x\n", nsres
);
2285 nsAString_Finish(&nsstr
);
2287 event
= alloc_event(nsevent
, event_id
);
2289 return E_OUTOFMEMORY
;
2295 HRESULT
create_document_event_str(HTMLDocumentNode
*doc
, const WCHAR
*type
, IDOMEvent
**ret_event
)
2297 nsIDOMEvent
*nsevent
;
2302 nsAString_InitDepend(&nsstr
, type
);
2303 nsres
= nsIDOMHTMLDocument_CreateEvent(doc
->nsdoc
, &nsstr
, &nsevent
);
2304 nsAString_Finish(&nsstr
);
2305 if(NS_FAILED(nsres
)) {
2306 FIXME("CreateEvent(%s) failed: %08x\n", debugstr_w(type
), nsres
);
2310 event
= alloc_event(nsevent
, EVENTID_LAST
);
2311 nsIDOMEvent_Release(nsevent
);
2313 return E_OUTOFMEMORY
;
2315 *ret_event
= &event
->IDOMEvent_iface
;
2319 HRESULT
create_document_event(HTMLDocumentNode
*doc
, eventid_t event_id
, DOMEvent
**ret_event
)
2321 nsIDOMEvent
*nsevent
;
2326 nsAString_InitDepend(&nsstr
, event_types
[event_info
[event_id
].type
]);
2327 nsres
= nsIDOMHTMLDocument_CreateEvent(doc
->nsdoc
, &nsstr
, &nsevent
);
2328 nsAString_Finish(&nsstr
);
2329 if(NS_FAILED(nsres
)) {
2330 FIXME("CreateEvent(%s) failed: %08x\n", debugstr_w(event_types
[event_info
[event_id
].type
]), nsres
);
2334 event
= alloc_event(nsevent
, event_id
);
2336 return E_OUTOFMEMORY
;
2338 event
->event_id
= event_id
;
2343 static HRESULT
call_disp_func(IDispatch
*disp
, DISPPARAMS
*dp
, VARIANT
*retv
)
2345 IDispatchEx
*dispex
;
2349 memset(&ei
, 0, sizeof(ei
));
2351 hres
= IDispatch_QueryInterface(disp
, &IID_IDispatchEx
, (void**)&dispex
);
2352 if(SUCCEEDED(hres
)) {
2353 hres
= IDispatchEx_InvokeEx(dispex
, 0, GetUserDefaultLCID(), DISPATCH_METHOD
, dp
, retv
, &ei
, NULL
);
2354 IDispatchEx_Release(dispex
);
2356 TRACE("Could not get IDispatchEx interface: %08x\n", hres
);
2357 hres
= IDispatch_Invoke(disp
, 0, &IID_NULL
, GetUserDefaultLCID(), DISPATCH_METHOD
,
2358 dp
, retv
, &ei
, NULL
);
2364 static HRESULT
call_cp_func(IDispatch
*disp
, DISPID dispid
, IHTMLEventObj
*event_obj
, VARIANT
*retv
)
2366 DISPPARAMS dp
= {NULL
,NULL
,0,0};
2371 TRACE("%p,%d,%p,%p\n", disp
, dispid
, event_obj
, retv
);
2374 V_VT(&event_arg
) = VT_DISPATCH
;
2375 V_DISPATCH(&event_arg
) = (IDispatch
*)event_obj
;
2376 dp
.rgvarg
= &event_arg
;
2380 memset(&ei
, 0, sizeof(ei
));
2381 return IDispatch_Invoke(disp
, dispid
, &IID_NULL
, 0, DISPATCH_METHOD
, &dp
, retv
, &ei
, &argerr
);
2384 static BOOL
use_event_quirks(EventTarget
*event_target
)
2386 return dispex_compat_mode(&event_target
->dispex
) < COMPAT_MODE_IE9
;
2389 static BOOL
is_cp_event(cp_static_data_t
*data
, DISPID dispid
)
2394 if(!data
|| dispid
== DISPID_UNKNOWN
)
2398 hres
= get_dispids(data
->tid
, &data
->id_cnt
, &data
->ids
);
2404 max
= data
->id_cnt
-1;
2407 if(data
->ids
[i
] == dispid
)
2410 if(data
->ids
[i
] < dispid
)
2419 static void call_event_handlers(EventTarget
*event_target
, DOMEvent
*event
, dispatch_mode_t dispatch_mode
)
2421 const listener_container_t
*container
= get_listener_container(event_target
, event
->type
, FALSE
);
2422 event_listener_t
*listener
, listeners_buf
[8], *listeners
= listeners_buf
;
2423 unsigned listeners_cnt
, listeners_size
;
2424 ConnectionPointContainer
*cp_container
= NULL
;
2425 const event_target_vtbl_t
*vtbl
= NULL
;
2426 BOOL skip_onevent_listener
= FALSE
;
2430 assert(!event
->current_target
);
2431 event
->current_target
= event_target
;
2433 if(container
&& !list_empty(&container
->listeners
) && event
->phase
!= DEP_CAPTURING_PHASE
) {
2434 listener
= LIST_ENTRY(list_tail(&container
->listeners
), event_listener_t
, entry
);
2435 if(listener
&& listener
->function
&& listener
->type
== LISTENER_TYPE_ONEVENT
2436 && use_event_quirks(event_target
)) {
2437 DISPID named_arg
= DISPID_THIS
;
2439 DISPPARAMS dp
= {&arg
, &named_arg
, 1, 1};
2441 skip_onevent_listener
= TRUE
;
2443 V_VT(&arg
) = VT_DISPATCH
;
2444 V_DISPATCH(&arg
) = (IDispatch
*)&event_target
->dispex
.IDispatchEx_iface
;
2445 V_VT(&v
) = VT_EMPTY
;
2447 TRACE("%s >>>\n", debugstr_w(event
->type
));
2448 hres
= call_disp_func(listener
->function
, &dp
, &v
);
2450 TRACE("%s <<< %s\n", debugstr_w(event
->type
), debugstr_variant(&v
));
2452 if(event
->cancelable
) {
2453 if(V_VT(&v
) == VT_BOOL
) {
2455 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
2456 }else if(V_VT(&v
) != VT_EMPTY
) {
2457 FIXME("unhandled result %s\n", debugstr_variant(&v
));
2462 WARN("%s <<< %08x\n", debugstr_w(event
->type
), hres
);
2468 listeners_size
= ARRAY_SIZE(listeners_buf
);
2471 LIST_FOR_EACH_ENTRY(listener
, &container
->listeners
, event_listener_t
, entry
) {
2472 if(!listener
->function
)
2474 switch(listener
->type
) {
2475 case LISTENER_TYPE_ONEVENT
:
2476 if(skip_onevent_listener
|| event
->phase
== DEP_CAPTURING_PHASE
)
2479 case LISTENER_TYPE_CAPTURE
:
2480 if(event
->phase
== DEP_BUBBLING_PHASE
|| dispatch_mode
== DISPATCH_LEGACY
)
2483 case LISTENER_TYPE_BUBBLE
:
2484 if(event
->phase
== DEP_CAPTURING_PHASE
|| dispatch_mode
== DISPATCH_LEGACY
)
2487 case LISTENER_TYPE_ATTACHED
:
2488 if(event
->phase
== DEP_CAPTURING_PHASE
|| dispatch_mode
== DISPATCH_STANDARD
)
2493 if(listeners_cnt
== listeners_size
) {
2494 event_listener_t
*new_listeners
;
2495 if(listeners
== listeners_buf
) {
2496 new_listeners
= heap_alloc(listeners_size
* 2 * sizeof(*new_listeners
));
2499 memcpy(new_listeners
, listeners
, listeners_cnt
* sizeof(*listeners
));
2501 new_listeners
= heap_realloc(listeners
, listeners_size
* 2 * sizeof(*new_listeners
));
2503 listeners
= new_listeners
;
2504 listeners_size
*= 2;
2507 listeners
[listeners_cnt
].type
= listener
->type
;
2508 IDispatch_AddRef(listeners
[listeners_cnt
].function
= listener
->function
);
2513 for(listener
= listeners
; !event
->stop_immediate_propagation
2514 && listener
< listeners
+ listeners_cnt
; listener
++) {
2515 if(listener
->type
!= LISTENER_TYPE_ATTACHED
) {
2516 DISPID named_arg
= DISPID_THIS
;
2518 DISPPARAMS dp
= {args
, &named_arg
, 2, 1};
2520 V_VT(args
) = VT_DISPATCH
;
2521 V_DISPATCH(args
) = (IDispatch
*)&event_target
->dispex
.IDispatchEx_iface
;
2522 V_VT(args
+1) = VT_DISPATCH
;
2523 V_DISPATCH(args
+1) = dispatch_mode
== DISPATCH_LEGACY
2524 ? (IDispatch
*)event
->event_obj
: (IDispatch
*)&event
->IDOMEvent_iface
;
2525 V_VT(&v
) = VT_EMPTY
;
2527 TRACE("%s >>>\n", debugstr_w(event
->type
));
2528 hres
= call_disp_func(listener
->function
, &dp
, &v
);
2530 TRACE("%s <<< %s\n", debugstr_w(event
->type
),
2531 debugstr_variant(&v
));
2533 if(event
->cancelable
) {
2534 if(V_VT(&v
) == VT_BOOL
) {
2536 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
2537 }else if(V_VT(&v
) != VT_EMPTY
) {
2538 FIXME("unhandled result %s\n", debugstr_variant(&v
));
2543 WARN("%s <<< %08x\n", debugstr_w(event
->type
), hres
);
2547 DISPPARAMS dp
= {&arg
, NULL
, 1, 0};
2549 V_VT(&arg
) = VT_DISPATCH
;
2550 V_DISPATCH(&arg
) = (IDispatch
*)event
->event_obj
;
2551 V_VT(&v
) = VT_EMPTY
;
2553 TRACE("%s attached >>>\n", debugstr_w(event
->type
));
2554 hres
= call_disp_func(listener
->function
, &dp
, &v
);
2556 TRACE("%s attached <<<\n", debugstr_w(event
->type
));
2558 if(event
->cancelable
) {
2559 if(V_VT(&v
) == VT_BOOL
) {
2561 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
2562 }else if(V_VT(&v
) != VT_EMPTY
) {
2563 FIXME("unhandled result %s\n", debugstr_variant(&v
));
2568 WARN("%s attached <<< %08x\n", debugstr_w(event
->type
), hres
);
2573 for(listener
= listeners
; listener
< listeners
+ listeners_cnt
; listener
++)
2574 IDispatch_Release(listener
->function
);
2575 if(listeners
!= listeners_buf
)
2576 heap_free(listeners
);
2578 if(event
->phase
!= DEP_CAPTURING_PHASE
&& event
->event_id
!= EVENTID_LAST
2579 && event_info
[event
->event_id
].dispid
&& (vtbl
= dispex_get_vtbl(&event_target
->dispex
))
2580 && vtbl
->get_cp_container
)
2581 cp_container
= vtbl
->get_cp_container(&event_target
->dispex
);
2583 if(cp_container
->cps
) {
2584 ConnectionPoint
*cp
;
2587 for(j
=0; cp_container
->cp_entries
[j
].riid
; j
++) {
2588 cp
= cp_container
->cps
+ j
;
2589 if(!cp
->sinks_size
|| !is_cp_event(cp
->data
, event_info
[event
->event_id
].dispid
))
2592 for(i
=0; i
< cp
->sinks_size
; i
++) {
2593 if(!cp
->sinks
[i
].disp
)
2596 V_VT(&v
) = VT_EMPTY
;
2598 TRACE("cp %s [%u] >>>\n", debugstr_w(event
->type
), i
);
2599 hres
= call_cp_func(cp
->sinks
[i
].disp
, event_info
[event
->event_id
].dispid
,
2600 cp
->data
->pass_event_arg
? event
->event_obj
: NULL
, &v
);
2602 TRACE("cp %s [%u] <<<\n", debugstr_w(event
->type
), i
);
2604 if(event
->cancelable
) {
2605 if(V_VT(&v
) == VT_BOOL
) {
2607 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
2608 }else if(V_VT(&v
) != VT_EMPTY
) {
2609 FIXME("unhandled result %s\n", debugstr_variant(&v
));
2614 WARN("cp %s [%u] <<< %08x\n", debugstr_w(event
->type
), i
, hres
);
2619 IConnectionPointContainer_Release(&cp_container
->IConnectionPointContainer_iface
);
2622 event
->current_target
= NULL
;
2625 static HRESULT
dispatch_event_object(EventTarget
*event_target
, DOMEvent
*event
,
2626 dispatch_mode_t dispatch_mode
, VARIANT_BOOL
*r
)
2628 EventTarget
*target_chain_buf
[8], **target_chain
= target_chain_buf
;
2629 unsigned chain_cnt
, chain_buf_size
, i
;
2630 const event_target_vtbl_t
*vtbl
, *target_vtbl
;
2631 HTMLEventObj
*event_obj_ref
= NULL
;
2632 IHTMLEventObj
*prev_event
= NULL
;
2636 TRACE("(%p) %s\n", event_target
, debugstr_w(event
->type
));
2639 FIXME("Uninitialized event.\n");
2643 if(event
->current_target
) {
2644 FIXME("event is being dispatched.\n");
2648 iter
= event_target
;
2649 IEventTarget_AddRef(&event_target
->IEventTarget_iface
);
2652 chain_buf_size
= ARRAY_SIZE(target_chain_buf
);
2655 if(chain_cnt
== chain_buf_size
) {
2656 EventTarget
**new_chain
;
2657 if(target_chain
== target_chain_buf
) {
2658 new_chain
= heap_alloc(chain_buf_size
* 2 * sizeof(*new_chain
));
2661 memcpy(new_chain
, target_chain
, chain_buf_size
* sizeof(*new_chain
));
2663 new_chain
= heap_realloc(target_chain
, chain_buf_size
* 2 * sizeof(*new_chain
));
2667 chain_buf_size
*= 2;
2668 target_chain
= new_chain
;
2671 target_chain
[chain_cnt
++] = iter
;
2673 if(!(vtbl
= dispex_get_vtbl(&iter
->dispex
)) || !vtbl
->get_parent_event_target
)
2675 iter
= vtbl
->get_parent_event_target(&iter
->dispex
);
2678 if(!event
->event_obj
&& !event
->no_event_obj
) {
2679 event_obj_ref
= alloc_event_obj(event
);
2681 event
->event_obj
= &event_obj_ref
->IHTMLEventObj_iface
;
2684 target_vtbl
= dispex_get_vtbl(&event_target
->dispex
);
2685 if(target_vtbl
&& target_vtbl
->set_current_event
)
2686 prev_event
= target_vtbl
->set_current_event(&event_target
->dispex
, event
->event_obj
);
2689 IEventTarget_Release(&event
->target
->IEventTarget_iface
);
2690 event
->target
= event_target
;
2691 IEventTarget_AddRef(&event_target
->IEventTarget_iface
);
2693 event
->phase
= DEP_CAPTURING_PHASE
;
2695 while(!event
->stop_propagation
&& i
)
2696 call_event_handlers(target_chain
[i
--], event
, dispatch_mode
);
2698 if(!event
->stop_propagation
) {
2699 event
->phase
= DEP_AT_TARGET
;
2700 call_event_handlers(target_chain
[0], event
, dispatch_mode
);
2703 if(event
->bubbles
) {
2704 event
->phase
= DEP_BUBBLING_PHASE
;
2705 for(i
= 1; !event
->stop_propagation
&& i
< chain_cnt
; i
++)
2706 call_event_handlers(target_chain
[i
], event
, dispatch_mode
);
2710 *r
= variant_bool(!event
->prevent_default
);
2712 if(target_vtbl
&& target_vtbl
->set_current_event
) {
2713 prev_event
= target_vtbl
->set_current_event(&event_target
->dispex
, prev_event
);
2715 IHTMLEventObj_Release(prev_event
);
2718 if(event
->event_id
!= EVENTID_LAST
&& (event_info
[event
->event_id
].flags
& EVENT_HASDEFAULTHANDLERS
)) {
2719 BOOL prevent_default
= event
->prevent_default
;
2720 for(i
= 0; !prevent_default
&& i
< chain_cnt
; i
++) {
2721 vtbl
= dispex_get_vtbl(&target_chain
[i
]->dispex
);
2722 if(!vtbl
|| !vtbl
->handle_event_default
)
2724 hres
= vtbl
->handle_event_default(&event_target
->dispex
, event
->event_id
,
2725 event
->nsevent
, &prevent_default
);
2726 if(FAILED(hres
) || event
->stop_propagation
)
2729 nsIDOMEvent_PreventDefault(event
->nsevent
);
2733 event
->prevent_default
= FALSE
;
2735 event
->event_obj
= NULL
;
2736 IHTMLEventObj_Release(&event_obj_ref
->IHTMLEventObj_iface
);
2739 for(i
= 0; i
< chain_cnt
; i
++)
2740 IEventTarget_Release(&target_chain
[i
]->IEventTarget_iface
);
2741 if(target_chain
!= target_chain_buf
)
2742 heap_free(target_chain
);
2747 void dispatch_event(EventTarget
*event_target
, DOMEvent
*event
)
2749 dispatch_event_object(event_target
, event
, DISPATCH_BOTH
, NULL
);
2752 * We may have registered multiple Gecko listeners for the same event type,
2753 * but we already dispatched event to all relevant targets. Stop event
2754 * propagation here to avoid events being dispatched multiple times.
2756 if(event
->event_id
!= EVENTID_LAST
&& (event_info
[event
->event_id
].flags
& EVENT_BIND_TO_TARGET
))
2757 nsIDOMEvent_StopPropagation(event
->nsevent
);
2760 HRESULT
fire_event(HTMLDOMNode
*node
, const WCHAR
*event_name
, VARIANT
*event_var
, VARIANT_BOOL
*cancelled
)
2762 HTMLEventObj
*event_obj
= NULL
;
2764 HRESULT hres
= S_OK
;
2766 eid
= attr_to_eid(event_name
);
2767 if(eid
== EVENTID_LAST
) {
2768 WARN("unknown event %s\n", debugstr_w(event_name
));
2769 return E_INVALIDARG
;
2772 if(event_var
&& V_VT(event_var
) != VT_EMPTY
&& V_VT(event_var
) != VT_ERROR
) {
2773 if(V_VT(event_var
) != VT_DISPATCH
) {
2774 FIXME("event_var %s not supported\n", debugstr_variant(event_var
));
2778 if(V_DISPATCH(event_var
)) {
2779 IHTMLEventObj
*event_iface
;
2781 hres
= IDispatch_QueryInterface(V_DISPATCH(event_var
), &IID_IHTMLEventObj
, (void**)&event_iface
);
2783 FIXME("No IHTMLEventObj iface\n");
2787 event_obj
= unsafe_impl_from_IHTMLEventObj(event_iface
);
2789 ERR("Not our IHTMLEventObj?\n");
2790 IHTMLEventObj_Release(event_iface
);
2797 event_obj
= alloc_event_obj(NULL
);
2799 return E_OUTOFMEMORY
;
2802 if(!event_obj
->event
)
2803 hres
= create_document_event(node
->doc
, eid
, &event_obj
->event
);
2805 if(SUCCEEDED(hres
)) {
2806 event_obj
->event
->event_obj
= &event_obj
->IHTMLEventObj_iface
;
2807 dispatch_event_object(&node
->event_target
, event_obj
->event
, DISPATCH_LEGACY
, NULL
);
2808 event_obj
->event
->event_obj
= NULL
;
2811 IHTMLEventObj_Release(&event_obj
->IHTMLEventObj_iface
);
2815 *cancelled
= VARIANT_TRUE
; /* FIXME */
2819 HRESULT
ensure_doc_nsevent_handler(HTMLDocumentNode
*doc
, nsIDOMNode
*nsnode
, eventid_t eid
)
2821 TRACE("%s\n", debugstr_w(event_info
[eid
].name
));
2827 case EVENTID_FOCUSIN
:
2828 doc
->event_vector
[eid
] = TRUE
;
2829 eid
= EVENTID_FOCUS
;
2831 case EVENTID_FOCUSOUT
:
2832 doc
->event_vector
[eid
] = TRUE
;
2841 if(event_info
[eid
].flags
& EVENT_DEFAULTLISTENER
) {
2843 }else if(event_info
[eid
].flags
& EVENT_BIND_TO_TARGET
) {
2845 nsnode
= doc
->node
.nsnode
;
2850 if(!nsnode
|| nsnode
== doc
->node
.nsnode
) {
2851 if(doc
->event_vector
[eid
])
2853 doc
->event_vector
[eid
] = TRUE
;
2856 add_nsevent_listener(doc
, nsnode
, event_info
[eid
].name
);
2860 void detach_events(HTMLDocumentNode
*doc
)
2862 if(doc
->event_vector
) {
2865 for(i
=0; i
< EVENTID_LAST
; i
++) {
2866 if(doc
->event_vector
[i
]) {
2867 detach_nsevent(doc
, event_info
[i
].name
);
2868 doc
->event_vector
[i
] = FALSE
;
2873 release_nsevents(doc
);
2876 static HRESULT
get_event_dispex_ref(EventTarget
*event_target
, eventid_t eid
, BOOL alloc
, VARIANT
**ret
)
2881 lstrcpyW(buf
+2, event_info
[eid
].name
);
2882 return dispex_get_dprop_ref(&event_target
->dispex
, buf
, alloc
, ret
);
2885 static event_listener_t
*get_onevent_listener(EventTarget
*event_target
, eventid_t eid
, BOOL alloc
)
2887 listener_container_t
*container
;
2888 event_listener_t
*listener
;
2890 container
= get_listener_container(event_target
, event_info
[eid
].name
, alloc
);
2894 LIST_FOR_EACH_ENTRY_REV(listener
, &container
->listeners
, event_listener_t
, entry
) {
2895 if(listener
->type
== LISTENER_TYPE_ONEVENT
)
2902 listener
= heap_alloc(sizeof(*listener
));
2906 listener
->type
= LISTENER_TYPE_ONEVENT
;
2907 listener
->function
= NULL
;
2908 list_add_tail(&container
->listeners
, &listener
->entry
);
2912 static void remove_event_handler(EventTarget
*event_target
, eventid_t eid
)
2914 event_listener_t
*listener
;
2918 hres
= get_event_dispex_ref(event_target
, eid
, FALSE
, &store
);
2920 VariantClear(store
);
2922 listener
= get_onevent_listener(event_target
, eid
, FALSE
);
2923 if(listener
&& listener
->function
) {
2924 IDispatch_Release(listener
->function
);
2925 listener
->function
= NULL
;
2929 static HRESULT
set_event_handler_disp(EventTarget
*event_target
, eventid_t eid
, IDispatch
*disp
)
2931 event_listener_t
*listener
;
2933 if(event_info
[eid
].flags
& EVENT_FIXME
)
2934 FIXME("unimplemented event %s\n", debugstr_w(event_info
[eid
].name
));
2936 remove_event_handler(event_target
, eid
);
2940 listener
= get_onevent_listener(event_target
, eid
, TRUE
);
2942 return E_OUTOFMEMORY
;
2944 if(listener
->function
)
2945 IDispatch_Release(listener
->function
);
2947 IDispatch_AddRef(listener
->function
= disp
);
2951 HRESULT
set_event_handler(EventTarget
*event_target
, eventid_t eid
, VARIANT
*var
)
2955 if(use_event_quirks(event_target
)) {
2956 WARN("attempt to set to VT_EMPTY in quirks mode\n");
2961 remove_event_handler(event_target
, eid
);
2965 return set_event_handler_disp(event_target
, eid
, V_DISPATCH(var
));
2971 if(!use_event_quirks(event_target
))
2972 FIXME("Setting to string %s not supported\n", debugstr_w(V_BSTR(var
)));
2975 * Setting event handler to string is a rare case and we don't want to
2976 * complicate nor increase memory of listener_container_t for that. Instead,
2977 * we store the value in DispatchEx, which can already handle custom
2980 remove_event_handler(event_target
, eid
);
2982 hres
= get_event_dispex_ref(event_target
, eid
, TRUE
, &v
);
2986 V_BSTR(v
) = SysAllocString(V_BSTR(var
));
2988 return E_OUTOFMEMORY
;
2994 FIXME("not handler %s\n", debugstr_variant(var
));
3001 HRESULT
get_event_handler(EventTarget
*event_target
, eventid_t eid
, VARIANT
*var
)
3003 event_listener_t
*listener
;
3007 hres
= get_event_dispex_ref(event_target
, eid
, FALSE
, &v
);
3008 if(SUCCEEDED(hres
) && V_VT(v
) != VT_EMPTY
) {
3009 V_VT(var
) = VT_EMPTY
;
3010 return VariantCopy(var
, v
);
3013 listener
= get_onevent_listener(event_target
, eid
, FALSE
);
3014 if(listener
&& listener
->function
) {
3015 V_VT(var
) = VT_DISPATCH
;
3016 V_DISPATCH(var
) = listener
->function
;
3017 IDispatch_AddRef(V_DISPATCH(var
));
3019 V_VT(var
) = VT_NULL
;
3025 HRESULT
attach_event(EventTarget
*event_target
, BSTR name
, IDispatch
*disp
, VARIANT_BOOL
*res
)
3027 listener_container_t
*container
;
3028 event_listener_t
*listener
;
3031 eid
= attr_to_eid(name
);
3032 if(eid
== EVENTID_LAST
) {
3033 WARN("Unknown event\n");
3034 *res
= VARIANT_TRUE
;
3038 container
= get_listener_container(event_target
, event_info
[eid
].name
, TRUE
);
3040 return E_OUTOFMEMORY
;
3042 listener
= heap_alloc(sizeof(*listener
));
3044 return E_OUTOFMEMORY
;
3046 listener
->type
= LISTENER_TYPE_ATTACHED
;
3047 IDispatch_AddRef(listener
->function
= disp
);
3048 if(use_event_quirks(event_target
))
3049 list_add_head(&container
->listeners
, &listener
->entry
);
3051 list_add_tail(&container
->listeners
, &listener
->entry
);
3053 *res
= VARIANT_TRUE
;
3057 HRESULT
detach_event(EventTarget
*event_target
, BSTR name
, IDispatch
*disp
)
3061 eid
= attr_to_eid(name
);
3062 if(eid
== EVENTID_LAST
) {
3063 WARN("Unknown event\n");
3067 remove_event_listener(event_target
, event_info
[eid
].name
, LISTENER_TYPE_ATTACHED
, disp
);
3071 void bind_target_event(HTMLDocumentNode
*doc
, EventTarget
*event_target
, const WCHAR
*event
, IDispatch
*disp
)
3075 TRACE("(%p %p %s %p)\n", doc
, event_target
, debugstr_w(event
), disp
);
3077 eid
= attr_to_eid(event
);
3078 if(eid
== EVENTID_LAST
) {
3079 WARN("Unsupported event %s\n", debugstr_w(event
));
3083 set_event_handler_disp(event_target
, eid
, disp
);
3086 void update_doc_cp_events(HTMLDocumentNode
*doc
, cp_static_data_t
*cp
)
3090 for(i
=0; i
< EVENTID_LAST
; i
++) {
3091 if((event_info
[i
].flags
& EVENT_DEFAULTLISTENER
) && is_cp_event(cp
, event_info
[i
].dispid
))
3092 ensure_doc_nsevent_handler(doc
, NULL
, i
);
3096 void check_event_attr(HTMLDocumentNode
*doc
, nsIDOMElement
*nselem
)
3098 nsIDOMMozNamedAttrMap
*attr_map
;
3099 const PRUnichar
*name
, *value
;
3100 nsAString name_str
, value_str
;
3101 HTMLDOMNode
*node
= NULL
;
3110 nsres
= nsIDOMElement_HasAttributes(nselem
, &has_attrs
);
3111 if(NS_FAILED(nsres
) || !has_attrs
)
3114 nsres
= nsIDOMElement_GetAttributes(nselem
, &attr_map
);
3115 if(NS_FAILED(nsres
))
3118 nsres
= nsIDOMMozNamedAttrMap_GetLength(attr_map
, &length
);
3119 assert(nsres
== NS_OK
);
3121 nsAString_Init(&name_str
, NULL
);
3122 nsAString_Init(&value_str
, NULL
);
3124 for(i
= 0; i
< length
; i
++) {
3125 nsres
= nsIDOMMozNamedAttrMap_Item(attr_map
, i
, &attr
);
3126 if(NS_FAILED(nsres
))
3129 nsres
= nsIDOMAttr_GetName(attr
, &name_str
);
3130 if(NS_FAILED(nsres
)) {
3131 nsIDOMAttr_Release(attr
);
3135 nsAString_GetData(&name_str
, &name
);
3136 eid
= attr_to_eid(name
);
3137 if(eid
== EVENTID_LAST
) {
3138 nsIDOMAttr_Release(attr
);
3142 nsres
= nsIDOMAttr_GetValue(attr
, &value_str
);
3143 nsIDOMAttr_Release(attr
);
3144 if(NS_FAILED(nsres
))
3147 nsAString_GetData(&value_str
, &value
);
3151 TRACE("%p.%s = %s\n", nselem
, debugstr_w(name
), debugstr_w(value
));
3153 disp
= script_parse_event(doc
->window
, value
);
3158 hres
= get_node((nsIDOMNode
*)nselem
, TRUE
, &node
);
3160 IDispatch_Release(disp
);
3165 set_event_handler_disp(get_node_event_prop_target(node
, eid
), eid
, disp
);
3166 IDispatch_Release(disp
);
3171 nsAString_Finish(&name_str
);
3172 nsAString_Finish(&value_str
);
3173 nsIDOMMozNamedAttrMap_Release(attr_map
);
3176 HRESULT
doc_init_events(HTMLDocumentNode
*doc
)
3181 doc
->event_vector
= heap_alloc_zero(EVENTID_LAST
*sizeof(BOOL
));
3182 if(!doc
->event_vector
)
3183 return E_OUTOFMEMORY
;
3187 for(i
=0; i
< EVENTID_LAST
; i
++) {
3188 if(event_info
[i
].flags
& EVENT_HASDEFAULTHANDLERS
) {
3189 hres
= ensure_doc_nsevent_handler(doc
, NULL
, i
);
3198 static inline EventTarget
*impl_from_IEventTarget(IEventTarget
*iface
)
3200 return CONTAINING_RECORD(iface
, EventTarget
, IEventTarget_iface
);
3203 static HRESULT WINAPI
EventTarget_QueryInterface(IEventTarget
*iface
, REFIID riid
, void **ppv
)
3205 EventTarget
*This
= impl_from_IEventTarget(iface
);
3206 return IDispatchEx_QueryInterface(&This
->dispex
.IDispatchEx_iface
, riid
, ppv
);
3209 static ULONG WINAPI
EventTarget_AddRef(IEventTarget
*iface
)
3211 EventTarget
*This
= impl_from_IEventTarget(iface
);
3212 return IDispatchEx_AddRef(&This
->dispex
.IDispatchEx_iface
);
3215 static ULONG WINAPI
EventTarget_Release(IEventTarget
*iface
)
3217 EventTarget
*This
= impl_from_IEventTarget(iface
);
3218 return IDispatchEx_Release(&This
->dispex
.IDispatchEx_iface
);
3221 static HRESULT WINAPI
EventTarget_GetTypeInfoCount(IEventTarget
*iface
, UINT
*pctinfo
)
3223 EventTarget
*This
= impl_from_IEventTarget(iface
);
3224 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
3227 static HRESULT WINAPI
EventTarget_GetTypeInfo(IEventTarget
*iface
, UINT iTInfo
,
3228 LCID lcid
, ITypeInfo
**ppTInfo
)
3230 EventTarget
*This
= impl_from_IEventTarget(iface
);
3231 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
3234 static HRESULT WINAPI
EventTarget_GetIDsOfNames(IEventTarget
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
3235 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
3237 EventTarget
*This
= impl_from_IEventTarget(iface
);
3238 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
,
3239 rgszNames
, cNames
, lcid
, rgDispId
);
3242 static HRESULT WINAPI
EventTarget_Invoke(IEventTarget
*iface
, DISPID dispIdMember
,
3243 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
3244 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
3246 EventTarget
*This
= impl_from_IEventTarget(iface
);
3247 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
,
3248 riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
3251 static HRESULT WINAPI
EventTarget_addEventListener(IEventTarget
*iface
, BSTR type
,
3252 IDispatch
*function
, VARIANT_BOOL capture
)
3254 EventTarget
*This
= impl_from_IEventTarget(iface
);
3255 listener_type_t listener_type
= capture
? LISTENER_TYPE_CAPTURE
: LISTENER_TYPE_BUBBLE
;
3256 listener_container_t
*container
;
3257 event_listener_t
*listener
;
3259 TRACE("(%p)->(%s %p %x)\n", This
, debugstr_w(type
), function
, capture
);
3261 container
= get_listener_container(This
, type
, TRUE
);
3263 return E_OUTOFMEMORY
;
3265 /* check for duplicates */
3266 LIST_FOR_EACH_ENTRY(listener
, &container
->listeners
, event_listener_t
, entry
) {
3267 if(listener
->type
== listener_type
&& listener
->function
== function
)
3271 listener
= heap_alloc(sizeof(*listener
));
3273 return E_OUTOFMEMORY
;
3275 listener
->type
= listener_type
;
3276 IDispatch_AddRef(listener
->function
= function
);
3277 list_add_tail(&container
->listeners
, &listener
->entry
);
3281 static HRESULT WINAPI
EventTarget_removeEventListener(IEventTarget
*iface
, BSTR type
,
3282 IDispatch
*listener
, VARIANT_BOOL capture
)
3284 EventTarget
*This
= impl_from_IEventTarget(iface
);
3286 TRACE("(%p)->(%s %p %x)\n", This
, debugstr_w(type
), listener
, capture
);
3288 remove_event_listener(This
, type
, capture
? LISTENER_TYPE_CAPTURE
: LISTENER_TYPE_BUBBLE
, listener
);
3292 static HRESULT WINAPI
EventTarget_dispatchEvent(IEventTarget
*iface
, IDOMEvent
*event_iface
, VARIANT_BOOL
*result
)
3294 EventTarget
*This
= impl_from_IEventTarget(iface
);
3295 DOMEvent
*event
= unsafe_impl_from_IDOMEvent(event_iface
);
3297 TRACE("(%p)->(%p %p)\n", This
, event
, result
);
3300 WARN("Invalid event\n");
3301 return E_INVALIDARG
;
3304 return dispatch_event_object(This
, event
, DISPATCH_STANDARD
, result
);
3307 static HRESULT
IEventTarget_addEventListener_hook(DispatchEx
*dispex
, LCID lcid
, WORD flags
,
3308 DISPPARAMS
*dp
, VARIANT
*res
, EXCEPINFO
*ei
, IServiceProvider
*caller
)
3310 /* If only two arguments were given, implicitly set capture to false */
3311 if((flags
& DISPATCH_METHOD
) && dp
->cArgs
== 2 && !dp
->cNamedArgs
) {
3313 DISPPARAMS new_dp
= {args
, NULL
, 3, 0};
3314 V_VT(args
) = VT_BOOL
;
3315 V_BOOL(args
) = VARIANT_FALSE
;
3316 args
[1] = dp
->rgvarg
[0];
3317 args
[2] = dp
->rgvarg
[1];
3319 TRACE("implicit capture\n");
3321 return IDispatchEx_InvokeEx(&dispex
->IDispatchEx_iface
, DISPID_IEVENTTARGET_ADDEVENTLISTENER
,
3322 lcid
, flags
, &new_dp
, res
, ei
, caller
);
3325 return S_FALSE
; /* fallback to default */
3328 static HRESULT
IEventTarget_removeEventListener_hook(DispatchEx
*dispex
, LCID lcid
, WORD flags
,
3329 DISPPARAMS
*dp
, VARIANT
*res
, EXCEPINFO
*ei
, IServiceProvider
*caller
)
3331 /* If only two arguments were given, implicitly set capture to false */
3332 if((flags
& DISPATCH_METHOD
) && dp
->cArgs
== 2 && !dp
->cNamedArgs
) {
3334 DISPPARAMS new_dp
= {args
, NULL
, 3, 0};
3335 V_VT(args
) = VT_BOOL
;
3336 V_BOOL(args
) = VARIANT_FALSE
;
3337 args
[1] = dp
->rgvarg
[0];
3338 args
[2] = dp
->rgvarg
[1];
3340 TRACE("implicit capture\n");
3342 return IDispatchEx_InvokeEx(&dispex
->IDispatchEx_iface
, DISPID_IEVENTTARGET_REMOVEEVENTLISTENER
,
3343 lcid
, flags
, &new_dp
, res
, ei
, caller
);
3346 return S_FALSE
; /* fallback to default */
3349 static const IEventTargetVtbl EventTargetVtbl
= {
3350 EventTarget_QueryInterface
,
3352 EventTarget_Release
,
3353 EventTarget_GetTypeInfoCount
,
3354 EventTarget_GetTypeInfo
,
3355 EventTarget_GetIDsOfNames
,
3357 EventTarget_addEventListener
,
3358 EventTarget_removeEventListener
,
3359 EventTarget_dispatchEvent
3362 static EventTarget
*unsafe_impl_from_IEventTarget(IEventTarget
*iface
)
3364 return iface
&& iface
->lpVtbl
== &EventTargetVtbl
? impl_from_IEventTarget(iface
) : NULL
;
3367 static HRESULT
get_gecko_target(IEventTarget
*target
, nsIDOMEventTarget
**ret
)
3369 EventTarget
*event_target
= unsafe_impl_from_IEventTarget(target
);
3370 const event_target_vtbl_t
*vtbl
;
3374 WARN("Not our IEventTarget implementation\n");
3375 return E_INVALIDARG
;
3378 vtbl
= (const event_target_vtbl_t
*)dispex_get_vtbl(&event_target
->dispex
);
3379 nsres
= nsISupports_QueryInterface(vtbl
->get_gecko_target(&event_target
->dispex
),
3380 &IID_nsIDOMEventTarget
, (void**)ret
);
3381 assert(nsres
== NS_OK
);
3385 HRESULT
EventTarget_QI(EventTarget
*event_target
, REFIID riid
, void **ppv
)
3387 if(IsEqualGUID(riid
, &IID_IEventTarget
)) {
3388 if(use_event_quirks(event_target
)) {
3389 WARN("IEventTarget queried, but not supported by in document mode\n");
3391 return E_NOINTERFACE
;
3393 IEventTarget_AddRef(&event_target
->IEventTarget_iface
);
3394 *ppv
= &event_target
->IEventTarget_iface
;
3398 if(dispex_query_interface(&event_target
->dispex
, riid
, ppv
))
3399 return *ppv
? S_OK
: E_NOINTERFACE
;
3401 WARN("(%p)->(%s %p)\n", event_target
, debugstr_mshtml_guid(riid
), ppv
);
3403 return E_NOINTERFACE
;
3406 void EventTarget_init_dispex_info(dispex_data_t
*dispex_info
, compat_mode_t compat_mode
)
3408 static const dispex_hook_t IEventTarget_hooks
[] = {
3409 {DISPID_IEVENTTARGET_ADDEVENTLISTENER
, IEventTarget_addEventListener_hook
},
3410 {DISPID_IEVENTTARGET_REMOVEEVENTLISTENER
, IEventTarget_removeEventListener_hook
},
3414 if(compat_mode
>= COMPAT_MODE_IE9
)
3415 dispex_info_add_interface(dispex_info
, IEventTarget_tid
, IEventTarget_hooks
);
3418 static int event_id_cmp(const void *key
, const struct wine_rb_entry
*entry
)
3420 return wcscmp(key
, WINE_RB_ENTRY_VALUE(entry
, listener_container_t
, entry
)->type
);
3423 void EventTarget_Init(EventTarget
*event_target
, IUnknown
*outer
, dispex_static_data_t
*dispex_data
,
3424 compat_mode_t compat_mode
)
3426 init_dispex_with_compat_mode(&event_target
->dispex
, outer
, dispex_data
, compat_mode
);
3427 event_target
->IEventTarget_iface
.lpVtbl
= &EventTargetVtbl
;
3428 wine_rb_init(&event_target
->handler_map
, event_id_cmp
);
3431 void release_event_target(EventTarget
*event_target
)
3433 listener_container_t
*iter
, *iter2
;
3435 WINE_RB_FOR_EACH_ENTRY_DESTRUCTOR(iter
, iter2
, &event_target
->handler_map
, listener_container_t
, entry
) {
3436 while(!list_empty(&iter
->listeners
)) {
3437 event_listener_t
*listener
= LIST_ENTRY(list_head(&iter
->listeners
), event_listener_t
, entry
);
3438 if(listener
->function
)
3439 IDispatch_Release(listener
->function
);
3440 list_remove(&listener
->entry
);
3441 heap_free(listener
);