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
29 #include "mshtml_private.h"
30 #include "htmlevent.h"
31 #include "htmlscript.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
38 LISTENER_TYPE_CAPTURE
,
40 LISTENER_TYPE_ONEVENT
,
41 LISTENER_TYPE_ATTACHED
51 struct wine_rb_entry entry
;
52 struct list listeners
;
54 } listener_container_t
;
73 static const WCHAR
*event_types
[] = {
91 /* Use Gecko default listener (it's registered on window object for DOM nodes). */
92 #define EVENT_DEFAULTLISTENER 0x0001
93 /* Register Gecko listener on target itself (unlike EVENT_DEFAULTLISTENER). */
94 #define EVENT_BIND_TO_TARGET 0x0002
95 /* Event bubbles by default (unless explicitly specified otherwise). */
96 #define EVENT_BUBBLES 0x0004
97 /* Event is cancelable by default (unless explicitly specified otherwise). */
98 #define EVENT_CANCELABLE 0x0008
99 /* Event may have default handler (so we always have to register Gecko listener). */
100 #define EVENT_HASDEFAULTHANDLERS 0x0020
101 /* Ecent is not supported properly, print FIXME message when it's used. */
102 #define EVENT_FIXME 0x0040
104 /* mouse event flags for fromElement and toElement implementation */
105 #define EVENT_MOUSE_TO_RELATED 0x0100
106 #define EVENT_MOUSE_FROM_RELATED 0x0200
108 /* Keep these sorted case sensitively */
109 static const event_info_t event_info
[] = {
110 {L
"DOMContentLoaded", EVENT_TYPE_EVENT
, 0,
111 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
112 {L
"abort", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONABORT
,
113 EVENT_BIND_TO_TARGET
},
114 {L
"animationend", EVENT_TYPE_EVENT
, DISPID_EVPROP_ONANIMATIONEND
,
115 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
},
116 {L
"animationstart", EVENT_TYPE_EVENT
, DISPID_EVPROP_ONANIMATIONSTART
,
117 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
},
118 {L
"beforeactivate", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONBEFOREACTIVATE
,
119 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
120 {L
"beforeunload", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONBEFOREUNLOAD
,
121 EVENT_DEFAULTLISTENER
| EVENT_CANCELABLE
},
122 {L
"blur", EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONBLUR
,
123 EVENT_DEFAULTLISTENER
},
124 {L
"change", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONCHANGE
,
125 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
},
126 {L
"click", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONCLICK
,
127 EVENT_DEFAULTLISTENER
| EVENT_HASDEFAULTHANDLERS
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
128 {L
"contextmenu", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONCONTEXTMENU
,
129 EVENT_BUBBLES
| EVENT_CANCELABLE
},
130 {L
"dataavailable", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONDATAAVAILABLE
,
131 EVENT_FIXME
| EVENT_BUBBLES
},
132 {L
"dblclick", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONDBLCLICK
,
133 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
134 {L
"drag", EVENT_TYPE_DRAG
, DISPID_EVMETH_ONDRAG
,
135 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
136 {L
"dragstart", EVENT_TYPE_DRAG
, DISPID_EVMETH_ONDRAGSTART
,
137 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
138 {L
"error", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONERROR
,
139 EVENT_BIND_TO_TARGET
},
140 {L
"focus", EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONFOCUS
,
141 EVENT_DEFAULTLISTENER
},
142 {L
"focusin", EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONFOCUSIN
,
144 {L
"focusout", EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONFOCUSOUT
,
146 {L
"help", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONHELP
,
147 EVENT_BUBBLES
| EVENT_CANCELABLE
},
148 {L
"input", EVENT_TYPE_EVENT
, DISPID_UNKNOWN
,
149 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
},
150 {L
"keydown", EVENT_TYPE_KEYBOARD
, DISPID_EVMETH_ONKEYDOWN
,
151 EVENT_DEFAULTLISTENER
| EVENT_HASDEFAULTHANDLERS
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
152 {L
"keypress", EVENT_TYPE_KEYBOARD
, DISPID_EVMETH_ONKEYPRESS
,
153 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
154 {L
"keyup", EVENT_TYPE_KEYBOARD
, DISPID_EVMETH_ONKEYUP
,
155 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
156 {L
"load", EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONLOAD
,
157 EVENT_BIND_TO_TARGET
},
158 {L
"message", EVENT_TYPE_MESSAGE
, DISPID_EVMETH_ONMESSAGE
,
160 {L
"mousedown", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEDOWN
,
161 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
162 {L
"mousemove", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEMOVE
,
163 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
| EVENT_MOUSE_FROM_RELATED
},
164 {L
"mouseout", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEOUT
,
165 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
| EVENT_MOUSE_TO_RELATED
},
166 {L
"mouseover", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEOVER
,
167 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
| EVENT_MOUSE_FROM_RELATED
},
168 {L
"mouseup", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEUP
,
169 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
170 {L
"mousewheel", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEWHEEL
,
172 {L
"msthumbnailclick", EVENT_TYPE_MOUSE
, DISPID_EVPROP_ONMSTHUMBNAILCLICK
,
174 {L
"paste", EVENT_TYPE_CLIPBOARD
, DISPID_EVMETH_ONPASTE
,
175 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
176 {L
"readystatechange", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONREADYSTATECHANGE
,
178 {L
"resize", EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONRESIZE
,
179 EVENT_DEFAULTLISTENER
},
180 {L
"scroll", EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONSCROLL
,
181 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
/* FIXME: not for elements */},
182 {L
"selectionchange", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONSELECTIONCHANGE
,
184 {L
"selectstart", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONSELECTSTART
,
185 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
186 {L
"submit", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONSUBMIT
,
187 EVENT_DEFAULTLISTENER
| EVENT_HASDEFAULTHANDLERS
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
188 {L
"unload", EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONUNLOAD
,
192 C_ASSERT(ARRAY_SIZE(event_info
) == EVENTID_LAST
);
194 static eventid_t
str_to_eid(const WCHAR
*str
)
196 unsigned i
, a
= 0, b
= ARRAY_SIZE(event_info
);
201 if(!(c
= wcscmp(event_info
[i
].name
, str
)))
210 static eventid_t
attr_to_eid(const WCHAR
*str
)
212 unsigned i
, a
= 0, b
= ARRAY_SIZE(event_info
);
215 if((str
[0] != 'o' && str
[0] != 'O') || (str
[1] != 'n' && str
[1] != 'N'))
220 if(!(c
= wcscmp(event_info
[i
].name
, str
+2)))
221 return event_info
[i
].dispid
? i
: EVENTID_LAST
;
229 static listener_container_t
*get_listener_container(EventTarget
*event_target
, const WCHAR
*type
, BOOL alloc
)
231 const event_target_vtbl_t
*vtbl
;
232 listener_container_t
*container
;
233 struct wine_rb_entry
*entry
;
237 entry
= wine_rb_get(&event_target
->handler_map
, type
);
239 return WINE_RB_ENTRY_VALUE(entry
, listener_container_t
, entry
);
243 eid
= str_to_eid(type
);
244 if(eid
!= EVENTID_LAST
&& (event_info
[eid
].flags
& EVENT_FIXME
))
245 FIXME("unimplemented event %s\n", debugstr_w(event_info
[eid
].name
));
247 type_len
= lstrlenW(type
);
248 container
= heap_alloc(FIELD_OFFSET(listener_container_t
, type
[type_len
+1]));
251 memcpy(container
->type
, type
, (type_len
+ 1) * sizeof(WCHAR
));
252 list_init(&container
->listeners
);
253 vtbl
= dispex_get_vtbl(&event_target
->dispex
);
254 if (!vtbl
->bind_event
)
255 FIXME("Unsupported event binding on target %p\n", event_target
);
256 else if(eid
!= EVENTID_LAST
)
257 vtbl
->bind_event(&event_target
->dispex
, eid
);
259 wine_rb_put(&event_target
->handler_map
, container
->type
, &container
->entry
);
263 static void remove_event_listener(EventTarget
*event_target
, const WCHAR
*type_name
, listener_type_t type
, IDispatch
*function
)
265 listener_container_t
*container
;
266 event_listener_t
*listener
;
268 container
= get_listener_container(event_target
, type_name
, FALSE
);
272 LIST_FOR_EACH_ENTRY(listener
, &container
->listeners
, event_listener_t
, entry
) {
273 if(listener
->function
== function
&& listener
->type
== type
) {
274 IDispatch_Release(listener
->function
);
275 list_remove(&listener
->entry
);
282 static HRESULT
get_gecko_target(IEventTarget
*,nsIDOMEventTarget
**);
286 IHTMLEventObj IHTMLEventObj_iface
;
291 VARIANT return_value
;
294 static inline HTMLEventObj
*impl_from_IHTMLEventObj(IHTMLEventObj
*iface
)
296 return CONTAINING_RECORD(iface
, HTMLEventObj
, IHTMLEventObj_iface
);
299 static HRESULT WINAPI
HTMLEventObj_QueryInterface(IHTMLEventObj
*iface
, REFIID riid
, void **ppv
)
301 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
303 TRACE("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
305 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
306 *ppv
= &This
->IHTMLEventObj_iface
;
307 }else if(IsEqualGUID(&IID_IHTMLEventObj
, riid
)) {
308 *ppv
= &This
->IHTMLEventObj_iface
;
309 }else if(dispex_query_interface(&This
->dispex
, riid
, ppv
)) {
310 return *ppv
? S_OK
: E_NOINTERFACE
;
313 WARN("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
314 return E_NOINTERFACE
;
317 IUnknown_AddRef((IUnknown
*)*ppv
);
321 static ULONG WINAPI
HTMLEventObj_AddRef(IHTMLEventObj
*iface
)
323 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
324 LONG ref
= InterlockedIncrement(&This
->ref
);
326 TRACE("(%p) ref=%ld\n", This
, ref
);
331 static ULONG WINAPI
HTMLEventObj_Release(IHTMLEventObj
*iface
)
333 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
334 LONG ref
= InterlockedDecrement(&This
->ref
);
336 TRACE("(%p) ref=%ld\n", This
, ref
);
340 IDOMEvent_Release(&This
->event
->IDOMEvent_iface
);
341 release_dispex(&This
->dispex
);
348 static HRESULT WINAPI
HTMLEventObj_GetTypeInfoCount(IHTMLEventObj
*iface
, UINT
*pctinfo
)
350 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
351 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
354 static HRESULT WINAPI
HTMLEventObj_GetTypeInfo(IHTMLEventObj
*iface
, UINT iTInfo
,
355 LCID lcid
, ITypeInfo
**ppTInfo
)
357 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
358 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
361 static HRESULT WINAPI
HTMLEventObj_GetIDsOfNames(IHTMLEventObj
*iface
, REFIID riid
,
362 LPOLESTR
*rgszNames
, UINT cNames
,
363 LCID lcid
, DISPID
*rgDispId
)
365 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
366 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
370 static HRESULT WINAPI
HTMLEventObj_Invoke(IHTMLEventObj
*iface
, DISPID dispIdMember
,
371 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
372 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
374 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
375 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
376 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
379 static HRESULT WINAPI
HTMLEventObj_get_srcElement(IHTMLEventObj
*iface
, IHTMLElement
**p
)
381 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
383 TRACE("(%p)->(%p)\n", This
, p
);
390 return IDOMEvent_get_srcElement(&This
->event
->IDOMEvent_iface
, p
);
393 static HRESULT WINAPI
HTMLEventObj_get_altKey(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
395 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
396 cpp_bool ret
= FALSE
;
398 TRACE("(%p)->(%p)\n", This
, p
);
400 if(This
->event
&& This
->event
->mouse_event
)
401 return IDOMMouseEvent_get_altKey(&This
->event
->IDOMMouseEvent_iface
, p
);
403 if(This
->event
&& This
->event
->keyboard_event
)
404 return IDOMKeyboardEvent_get_altKey(&This
->event
->IDOMKeyboardEvent_iface
, p
);
406 *p
= variant_bool(ret
);
410 static HRESULT WINAPI
HTMLEventObj_get_ctrlKey(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
412 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
413 cpp_bool ret
= FALSE
;
415 TRACE("(%p)->(%p)\n", This
, p
);
417 if(This
->event
&& This
->event
->mouse_event
)
418 return IDOMMouseEvent_get_ctrlKey(&This
->event
->IDOMMouseEvent_iface
, p
);
420 if(This
->event
&& This
->event
->keyboard_event
)
421 return IDOMKeyboardEvent_get_ctrlKey(&This
->event
->IDOMKeyboardEvent_iface
, p
);
423 *p
= variant_bool(ret
);
427 static HRESULT WINAPI
HTMLEventObj_get_shiftKey(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
429 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
430 cpp_bool ret
= FALSE
;
432 TRACE("(%p)->(%p)\n", This
, p
);
434 if(This
->event
&& This
->event
->mouse_event
)
435 return IDOMMouseEvent_get_shiftKey(&This
->event
->IDOMMouseEvent_iface
, p
);
437 if(This
->event
&& This
->event
->keyboard_event
)
438 return IDOMKeyboardEvent_get_shiftKey(&This
->event
->IDOMKeyboardEvent_iface
, p
);
440 *p
= variant_bool(ret
);
444 static HRESULT WINAPI
HTMLEventObj_put_returnValue(IHTMLEventObj
*iface
, VARIANT v
)
446 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
448 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&v
));
450 if(V_VT(&v
) != VT_BOOL
) {
451 FIXME("unsupported value %s\n", debugstr_variant(&v
));
452 return DISP_E_BADVARTYPE
;
455 This
->return_value
= v
;
456 if(!V_BOOL(&v
) && This
->event
)
457 IDOMEvent_preventDefault(&This
->event
->IDOMEvent_iface
);
461 static HRESULT WINAPI
HTMLEventObj_get_returnValue(IHTMLEventObj
*iface
, VARIANT
*p
)
463 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
465 TRACE("(%p)->(%p)\n", This
, p
);
468 return VariantCopy(p
, &This
->return_value
);
471 static HRESULT WINAPI
HTMLEventObj_put_cancelBubble(IHTMLEventObj
*iface
, VARIANT_BOOL v
)
473 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
475 TRACE("(%p)->(%x)\n", This
, v
);
478 IDOMEvent_stopPropagation(&This
->event
->IDOMEvent_iface
);
482 static HRESULT WINAPI
HTMLEventObj_get_cancelBubble(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
484 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
486 TRACE("(%p)->(%p)\n", This
, p
);
488 *p
= variant_bool(This
->event
&& This
->event
->stop_propagation
);
492 static HRESULT WINAPI
HTMLEventObj_get_fromElement(IHTMLEventObj
*iface
, IHTMLElement
**p
)
494 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
496 TRACE("(%p)->(%p)\n", This
, p
);
498 if(This
->event
&& This
->event
->mouse_event
)
499 return IDOMMouseEvent_get_fromElement(&This
->event
->IDOMMouseEvent_iface
, p
);
505 static HRESULT WINAPI
HTMLEventObj_get_toElement(IHTMLEventObj
*iface
, IHTMLElement
**p
)
507 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
509 TRACE("(%p)->(%p)\n", This
, p
);
511 if(This
->event
&& This
->event
->mouse_event
)
512 return IDOMMouseEvent_get_toElement(&This
->event
->IDOMMouseEvent_iface
, p
);
518 static HRESULT WINAPI
HTMLEventObj_put_keyCode(IHTMLEventObj
*iface
, LONG v
)
520 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
521 FIXME("(%p)->(%ld)\n", This
, v
);
525 static HRESULT WINAPI
HTMLEventObj_get_keyCode(IHTMLEventObj
*iface
, LONG
*p
)
527 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
529 TRACE("(%p)->(%p)\n", This
, p
);
531 if(This
->event
&& This
->event
->keyboard_event
)
532 return IDOMKeyboardEvent_get_keyCode(&This
->event
->IDOMKeyboardEvent_iface
, p
);
538 static HRESULT WINAPI
HTMLEventObj_get_button(IHTMLEventObj
*iface
, LONG
*p
)
540 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
543 TRACE("(%p)->(%p)\n", This
, p
);
545 if(This
->event
&& This
->event
->mouse_event
) {
547 hres
= IDOMMouseEvent_get_button(&This
->event
->IDOMMouseEvent_iface
, &button
);
556 static HRESULT WINAPI
HTMLEventObj_get_type(IHTMLEventObj
*iface
, BSTR
*p
)
558 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
560 TRACE("(%p)->(%p)\n", This
, p
);
567 return IDOMEvent_get_type(&This
->event
->IDOMEvent_iface
, p
);
570 static HRESULT WINAPI
HTMLEventObj_get_qualifier(IHTMLEventObj
*iface
, BSTR
*p
)
572 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
574 FIXME("(%p)->(%p)\n", This
, p
);
580 static HRESULT WINAPI
HTMLEventObj_get_reason(IHTMLEventObj
*iface
, LONG
*p
)
582 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
584 FIXME("(%p)->(%p)\n", This
, p
);
590 static HRESULT WINAPI
HTMLEventObj_get_x(IHTMLEventObj
*iface
, LONG
*p
)
592 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
595 TRACE("(%p)->(%p)\n", This
, p
);
597 if(This
->event
&& This
->event
->ui_event
) {
600 /* NOTE: pageX is not exactly right here. */
601 nsres
= nsIDOMUIEvent_GetPageX(This
->event
->ui_event
, &x
);
602 assert(nsres
== NS_OK
);
609 static HRESULT WINAPI
HTMLEventObj_get_y(IHTMLEventObj
*iface
, LONG
*p
)
611 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
614 TRACE("(%p)->(%p)\n", This
, p
);
616 if(This
->event
&& This
->event
->ui_event
) {
619 /* NOTE: pageY is not exactly right here. */
620 nsres
= nsIDOMUIEvent_GetPageY(This
->event
->ui_event
, &y
);
621 assert(nsres
== NS_OK
);
628 static HRESULT WINAPI
HTMLEventObj_get_clientX(IHTMLEventObj
*iface
, LONG
*p
)
630 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
632 TRACE("(%p)->(%p)\n", This
, p
);
634 if(This
->event
&& This
->event
->mouse_event
)
635 return IDOMMouseEvent_get_clientX(&This
->event
->IDOMMouseEvent_iface
, p
);
641 static HRESULT WINAPI
HTMLEventObj_get_clientY(IHTMLEventObj
*iface
, LONG
*p
)
643 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
645 TRACE("(%p)->(%p)\n", This
, p
);
647 if(This
->event
&& This
->event
->mouse_event
)
648 return IDOMMouseEvent_get_clientY(&This
->event
->IDOMMouseEvent_iface
, p
);
654 static HRESULT WINAPI
HTMLEventObj_get_offsetX(IHTMLEventObj
*iface
, LONG
*p
)
656 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
658 TRACE("(%p)->(%p)\n", This
, p
);
660 if(This
->event
&& This
->event
->mouse_event
)
661 return IDOMMouseEvent_get_offsetX(&This
->event
->IDOMMouseEvent_iface
, p
);
667 static HRESULT WINAPI
HTMLEventObj_get_offsetY(IHTMLEventObj
*iface
, LONG
*p
)
669 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
671 TRACE("(%p)->(%p)\n", This
, p
);
673 if(This
->event
&& This
->event
->mouse_event
)
674 return IDOMMouseEvent_get_offsetY(&This
->event
->IDOMMouseEvent_iface
, p
);
680 static HRESULT WINAPI
HTMLEventObj_get_screenX(IHTMLEventObj
*iface
, LONG
*p
)
682 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
684 TRACE("(%p)->(%p)\n", This
, p
);
686 if(This
->event
&& This
->event
->mouse_event
)
687 return IDOMMouseEvent_get_screenX(&This
->event
->IDOMMouseEvent_iface
, p
);
693 static HRESULT WINAPI
HTMLEventObj_get_screenY(IHTMLEventObj
*iface
, LONG
*p
)
695 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
697 TRACE("(%p)->(%p)\n", This
, p
);
699 if(This
->event
&& This
->event
->mouse_event
)
700 return IDOMMouseEvent_get_screenY(&This
->event
->IDOMMouseEvent_iface
, p
);
706 static HRESULT WINAPI
HTMLEventObj_get_srcFilter(IHTMLEventObj
*iface
, IDispatch
**p
)
708 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
710 FIXME("(%p)->(%p)\n", This
, p
);
716 static const IHTMLEventObjVtbl HTMLEventObjVtbl
= {
717 HTMLEventObj_QueryInterface
,
719 HTMLEventObj_Release
,
720 HTMLEventObj_GetTypeInfoCount
,
721 HTMLEventObj_GetTypeInfo
,
722 HTMLEventObj_GetIDsOfNames
,
724 HTMLEventObj_get_srcElement
,
725 HTMLEventObj_get_altKey
,
726 HTMLEventObj_get_ctrlKey
,
727 HTMLEventObj_get_shiftKey
,
728 HTMLEventObj_put_returnValue
,
729 HTMLEventObj_get_returnValue
,
730 HTMLEventObj_put_cancelBubble
,
731 HTMLEventObj_get_cancelBubble
,
732 HTMLEventObj_get_fromElement
,
733 HTMLEventObj_get_toElement
,
734 HTMLEventObj_put_keyCode
,
735 HTMLEventObj_get_keyCode
,
736 HTMLEventObj_get_button
,
737 HTMLEventObj_get_type
,
738 HTMLEventObj_get_qualifier
,
739 HTMLEventObj_get_reason
,
742 HTMLEventObj_get_clientX
,
743 HTMLEventObj_get_clientY
,
744 HTMLEventObj_get_offsetX
,
745 HTMLEventObj_get_offsetY
,
746 HTMLEventObj_get_screenX
,
747 HTMLEventObj_get_screenY
,
748 HTMLEventObj_get_srcFilter
751 static inline HTMLEventObj
*unsafe_impl_from_IHTMLEventObj(IHTMLEventObj
*iface
)
753 return iface
->lpVtbl
== &HTMLEventObjVtbl
? impl_from_IHTMLEventObj(iface
) : NULL
;
756 static const tid_t HTMLEventObj_iface_tids
[] = {
761 static dispex_static_data_t HTMLEventObj_dispex
= {
765 HTMLEventObj_iface_tids
768 static HTMLEventObj
*alloc_event_obj(DOMEvent
*event
, compat_mode_t compat_mode
)
770 HTMLEventObj
*event_obj
;
772 event_obj
= heap_alloc_zero(sizeof(*event_obj
));
776 event_obj
->IHTMLEventObj_iface
.lpVtbl
= &HTMLEventObjVtbl
;
778 event_obj
->event
= event
;
780 IDOMEvent_AddRef(&event
->IDOMEvent_iface
);
782 init_dispatch(&event_obj
->dispex
, (IUnknown
*)&event_obj
->IHTMLEventObj_iface
, &HTMLEventObj_dispex
, compat_mode
);
786 HRESULT
create_event_obj(compat_mode_t compat_mode
, IHTMLEventObj
**ret
)
788 HTMLEventObj
*event_obj
;
790 event_obj
= alloc_event_obj(NULL
, compat_mode
);
792 return E_OUTOFMEMORY
;
794 *ret
= &event_obj
->IHTMLEventObj_iface
;
798 static inline DOMEvent
*impl_from_IDOMEvent(IDOMEvent
*iface
)
800 return CONTAINING_RECORD(iface
, DOMEvent
, IDOMEvent_iface
);
803 static const IDOMEventVtbl DOMEventVtbl
;
805 static inline DOMEvent
*unsafe_impl_from_IDOMEvent(IDOMEvent
*iface
)
807 return iface
&& iface
->lpVtbl
== &DOMEventVtbl
? impl_from_IDOMEvent(iface
) : NULL
;
810 static HRESULT WINAPI
DOMEvent_QueryInterface(IDOMEvent
*iface
, REFIID riid
, void **ppv
)
812 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
814 TRACE("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
816 if(IsEqualGUID(&IID_IUnknown
, riid
))
817 *ppv
= &This
->IDOMEvent_iface
;
818 else if(IsEqualGUID(&IID_IDOMEvent
, riid
))
819 *ppv
= &This
->IDOMEvent_iface
;
820 else if(This
->ui_event
&& IsEqualGUID(&IID_IDOMUIEvent
, riid
))
821 *ppv
= &This
->IDOMUIEvent_iface
;
822 else if(This
->mouse_event
&& IsEqualGUID(&IID_IDOMMouseEvent
, riid
))
823 *ppv
= &This
->IDOMMouseEvent_iface
;
824 else if(This
->keyboard_event
&& IsEqualGUID(&IID_IDOMKeyboardEvent
, riid
))
825 *ppv
= &This
->IDOMKeyboardEvent_iface
;
826 else if(dispex_query_interface(&This
->dispex
, riid
, ppv
))
827 return *ppv
? S_OK
: E_NOINTERFACE
;
828 else if(!This
->query_interface
|| !(*ppv
= This
->query_interface(This
, riid
))) {
830 WARN("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
831 return E_NOINTERFACE
;
834 IUnknown_AddRef((IUnknown
*)*ppv
);
838 static ULONG WINAPI
DOMEvent_AddRef(IDOMEvent
*iface
)
840 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
841 LONG ref
= InterlockedIncrement(&This
->ref
);
843 TRACE("(%p) ref=%lu\n", This
, ref
);
848 static ULONG WINAPI
DOMEvent_Release(IDOMEvent
*iface
)
850 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
851 LONG ref
= InterlockedDecrement(&This
->ref
);
853 TRACE("(%p) ref=%lu\n", This
, ref
);
859 nsIDOMUIEvent_Release(This
->ui_event
);
860 if(This
->mouse_event
)
861 nsIDOMMouseEvent_Release(This
->mouse_event
);
862 if(This
->keyboard_event
)
863 nsIDOMKeyEvent_Release(This
->keyboard_event
);
865 IEventTarget_Release(&This
->target
->IEventTarget_iface
);
866 nsIDOMEvent_Release(This
->nsevent
);
867 release_dispex(&This
->dispex
);
868 heap_free(This
->type
);
875 static HRESULT WINAPI
DOMEvent_GetTypeInfoCount(IDOMEvent
*iface
, UINT
*pctinfo
)
877 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
878 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
881 static HRESULT WINAPI
DOMEvent_GetTypeInfo(IDOMEvent
*iface
, UINT iTInfo
,
882 LCID lcid
, ITypeInfo
**ppTInfo
)
884 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
885 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
888 static HRESULT WINAPI
DOMEvent_GetIDsOfNames(IDOMEvent
*iface
, REFIID riid
,
889 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
891 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
892 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
896 static HRESULT WINAPI
DOMEvent_Invoke(IDOMEvent
*iface
, DISPID dispIdMember
,
897 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
898 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
900 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
901 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
902 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
905 static HRESULT WINAPI
DOMEvent_get_bubbles(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
907 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
909 TRACE("(%p)->(%p)\n", This
, p
);
911 *p
= variant_bool(This
->bubbles
);
915 static HRESULT WINAPI
DOMEvent_get_cancelable(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
917 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
919 TRACE("(%p)->(%p)\n", This
, p
);
921 *p
= variant_bool(This
->cancelable
);
925 static HRESULT WINAPI
DOMEvent_get_currentTarget(IDOMEvent
*iface
, IEventTarget
**p
)
927 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
929 TRACE("(%p)->(%p)\n", This
, p
);
931 if(This
->current_target
)
932 IEventTarget_AddRef(*p
= &This
->current_target
->IEventTarget_iface
);
938 static HRESULT WINAPI
DOMEvent_get_defaultPrevented(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
940 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
942 TRACE("(%p)->(%p)\n", This
, p
);
944 *p
= variant_bool(This
->prevent_default
);
948 static HRESULT WINAPI
DOMEvent_get_eventPhase(IDOMEvent
*iface
, USHORT
*p
)
950 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
952 TRACE("(%p)->(%p)\n", This
, p
);
958 static HRESULT WINAPI
DOMEvent_get_target(IDOMEvent
*iface
, IEventTarget
**p
)
960 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
962 TRACE("(%p)->(%p)\n", This
, p
);
965 IEventTarget_AddRef(*p
= &This
->target
->IEventTarget_iface
);
971 static HRESULT WINAPI
DOMEvent_get_timeStamp(IDOMEvent
*iface
, ULONGLONG
*p
)
973 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
975 TRACE("(%p)->(%p)\n", This
, p
);
977 *p
= This
->time_stamp
;
981 static HRESULT WINAPI
DOMEvent_get_type(IDOMEvent
*iface
, BSTR
*p
)
983 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
985 TRACE("(%p)->(%p)\n", This
, p
);
988 *p
= SysAllocString(This
->type
);
990 return E_OUTOFMEMORY
;
998 #define nsIDOMEvent_InitEvent(_this,type,bubbles,cancelable) \
999 ((void (WINAPI*)(void*,nsIDOMEvent*,const nsAString*,cpp_bool,cpp_bool)) \
1000 &call_thiscall_func)((_this)->lpVtbl->InitEvent,_this,type,bubbles,cancelable)
1004 static HRESULT WINAPI
DOMEvent_initEvent(IDOMEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
, VARIANT_BOOL cancelable
)
1006 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1009 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_w(type
), can_bubble
, cancelable
);
1012 TRACE("called on already dispatched event\n");
1016 heap_free(This
->type
);
1017 This
->type
= heap_strdupW(type
);
1019 return E_OUTOFMEMORY
;
1020 This
->event_id
= str_to_eid(type
);
1022 This
->bubbles
= !!can_bubble
;
1023 This
->cancelable
= !!cancelable
;
1025 nsAString_InitDepend(&nsstr
, type
);
1026 nsIDOMEvent_InitEvent(This
->nsevent
, &nsstr
, This
->bubbles
, This
->cancelable
);
1027 nsAString_Finish(&nsstr
);
1032 static HRESULT WINAPI
DOMEvent_preventDefault(IDOMEvent
*iface
)
1034 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1036 TRACE("(%p)\n", This
);
1038 if(This
->current_target
&& This
->cancelable
) {
1039 This
->prevent_default
= TRUE
;
1040 nsIDOMEvent_PreventDefault(This
->nsevent
);
1045 static HRESULT WINAPI
DOMEvent_stopPropagation(IDOMEvent
*iface
)
1047 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1049 TRACE("(%p)\n", This
);
1051 This
->stop_propagation
= TRUE
;
1052 nsIDOMEvent_StopPropagation(This
->nsevent
);
1056 static HRESULT WINAPI
DOMEvent_stopImmediatePropagation(IDOMEvent
*iface
)
1058 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1060 TRACE("(%p)\n", This
);
1062 This
->stop_immediate_propagation
= This
->stop_propagation
= TRUE
;
1063 nsIDOMEvent_StopImmediatePropagation(This
->nsevent
);
1067 static HRESULT WINAPI
DOMEvent_get_isTrusted(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
1069 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1071 TRACE("(%p)->(%p)\n", This
, p
);
1073 *p
= variant_bool(This
->trusted
);
1077 static HRESULT WINAPI
DOMEvent_put_cancelBubble(IDOMEvent
*iface
, VARIANT_BOOL v
)
1079 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1080 FIXME("(%p)->(%x)\n", This
, v
);
1084 static HRESULT WINAPI
DOMEvent_get_cancelBubble(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
1086 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1087 FIXME("(%p)->(%p)\n", This
, p
);
1091 static HRESULT WINAPI
DOMEvent_get_srcElement(IDOMEvent
*iface
, IHTMLElement
**p
)
1093 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1095 TRACE("(%p)->(%p)\n", This
, p
);
1098 IDispatchEx_QueryInterface(&This
->target
->dispex
.IDispatchEx_iface
, &IID_IHTMLElement
, (void**)p
);
1104 static const IDOMEventVtbl DOMEventVtbl
= {
1105 DOMEvent_QueryInterface
,
1108 DOMEvent_GetTypeInfoCount
,
1109 DOMEvent_GetTypeInfo
,
1110 DOMEvent_GetIDsOfNames
,
1112 DOMEvent_get_bubbles
,
1113 DOMEvent_get_cancelable
,
1114 DOMEvent_get_currentTarget
,
1115 DOMEvent_get_defaultPrevented
,
1116 DOMEvent_get_eventPhase
,
1117 DOMEvent_get_target
,
1118 DOMEvent_get_timeStamp
,
1121 DOMEvent_preventDefault
,
1122 DOMEvent_stopPropagation
,
1123 DOMEvent_stopImmediatePropagation
,
1124 DOMEvent_get_isTrusted
,
1125 DOMEvent_put_cancelBubble
,
1126 DOMEvent_get_cancelBubble
,
1127 DOMEvent_get_srcElement
1130 static inline DOMEvent
*impl_from_IDOMUIEvent(IDOMUIEvent
*iface
)
1132 return CONTAINING_RECORD(iface
, DOMEvent
, IDOMUIEvent_iface
);
1135 static HRESULT WINAPI
DOMUIEvent_QueryInterface(IDOMUIEvent
*iface
, REFIID riid
, void **ppv
)
1137 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1138 return IDOMEvent_QueryInterface(&This
->IDOMEvent_iface
, riid
, ppv
);
1141 static ULONG WINAPI
DOMUIEvent_AddRef(IDOMUIEvent
*iface
)
1143 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1144 return IDOMEvent_AddRef(&This
->IDOMEvent_iface
);
1147 static ULONG WINAPI
DOMUIEvent_Release(IDOMUIEvent
*iface
)
1149 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1150 return IDOMEvent_Release(&This
->IDOMEvent_iface
);
1153 static HRESULT WINAPI
DOMUIEvent_GetTypeInfoCount(IDOMUIEvent
*iface
, UINT
*pctinfo
)
1155 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1156 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
1159 static HRESULT WINAPI
DOMUIEvent_GetTypeInfo(IDOMUIEvent
*iface
, UINT iTInfo
,
1160 LCID lcid
, ITypeInfo
**ppTInfo
)
1162 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1163 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1166 static HRESULT WINAPI
DOMUIEvent_GetIDsOfNames(IDOMUIEvent
*iface
, REFIID riid
,
1167 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1169 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1170 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1174 static HRESULT WINAPI
DOMUIEvent_Invoke(IDOMUIEvent
*iface
, DISPID dispIdMember
,
1175 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1176 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1178 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1179 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1180 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1183 static HRESULT WINAPI
DOMUIEvent_get_view(IDOMUIEvent
*iface
, IHTMLWindow2
**p
)
1185 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1186 mozIDOMWindowProxy
*moz_window
;
1187 HTMLOuterWindow
*view
= NULL
;
1190 TRACE("(%p)->(%p)\n", This
, p
);
1192 nsres
= nsIDOMUIEvent_GetView(This
->ui_event
, &moz_window
);
1193 if(NS_FAILED(nsres
))
1197 view
= mozwindow_to_window(moz_window
);
1198 mozIDOMWindowProxy_Release(moz_window
);
1201 IHTMLWindow2_AddRef((*p
= &view
->base
.inner_window
->base
.IHTMLWindow2_iface
));
1207 static HRESULT WINAPI
DOMUIEvent_get_detail(IDOMUIEvent
*iface
, LONG
*p
)
1209 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1213 TRACE("(%p)->(%p)\n", This
, p
);
1215 nsres
= nsIDOMUIEvent_GetDetail(This
->ui_event
, &detail
);
1216 if(NS_FAILED(nsres
))
1223 static HRESULT WINAPI
DOMUIEvent_initUIEvent(IDOMUIEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
1224 VARIANT_BOOL cancelable
, IHTMLWindow2
*view
, LONG detail
)
1226 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1231 TRACE("(%p)->(%s %x %x %p %lx)\n", This
, debugstr_w(type
), can_bubble
, cancelable
, view
, detail
);
1234 TRACE("called on already dispatched event\n");
1239 FIXME("view argument is not supported\n");
1241 hres
= IDOMEvent_initEvent(&This
->IDOMEvent_iface
, type
, can_bubble
, cancelable
);
1245 nsAString_InitDepend(&type_str
, type
);
1246 nsres
= nsIDOMUIEvent_InitUIEvent(This
->ui_event
, &type_str
, !!can_bubble
, !!cancelable
,
1247 NULL
/* FIXME */, detail
);
1248 nsAString_Finish(&type_str
);
1249 if(NS_FAILED(nsres
)) {
1250 FIXME("InitUIEvent failed: %08lx\n", nsres
);
1257 static const IDOMUIEventVtbl DOMUIEventVtbl
= {
1258 DOMUIEvent_QueryInterface
,
1261 DOMUIEvent_GetTypeInfoCount
,
1262 DOMUIEvent_GetTypeInfo
,
1263 DOMUIEvent_GetIDsOfNames
,
1265 DOMUIEvent_get_view
,
1266 DOMUIEvent_get_detail
,
1267 DOMUIEvent_initUIEvent
1270 static inline DOMEvent
*impl_from_IDOMMouseEvent(IDOMMouseEvent
*iface
)
1272 return CONTAINING_RECORD(iface
, DOMEvent
, IDOMMouseEvent_iface
);
1275 static HRESULT WINAPI
DOMMouseEvent_QueryInterface(IDOMMouseEvent
*iface
, REFIID riid
, void **ppv
)
1277 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1278 return IDOMEvent_QueryInterface(&This
->IDOMEvent_iface
, riid
, ppv
);
1281 static ULONG WINAPI
DOMMouseEvent_AddRef(IDOMMouseEvent
*iface
)
1283 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1284 return IDOMEvent_AddRef(&This
->IDOMEvent_iface
);
1287 static ULONG WINAPI
DOMMouseEvent_Release(IDOMMouseEvent
*iface
)
1289 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1290 return IDOMEvent_Release(&This
->IDOMEvent_iface
);
1293 static HRESULT WINAPI
DOMMouseEvent_GetTypeInfoCount(IDOMMouseEvent
*iface
, UINT
*pctinfo
)
1295 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1296 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
1299 static HRESULT WINAPI
DOMMouseEvent_GetTypeInfo(IDOMMouseEvent
*iface
, UINT iTInfo
,
1300 LCID lcid
, ITypeInfo
**ppTInfo
)
1302 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1303 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1306 static HRESULT WINAPI
DOMMouseEvent_GetIDsOfNames(IDOMMouseEvent
*iface
, REFIID riid
,
1307 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1309 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1310 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1314 static HRESULT WINAPI
DOMMouseEvent_Invoke(IDOMMouseEvent
*iface
, DISPID dispIdMember
,
1315 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1316 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1318 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1319 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1320 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1323 static HRESULT WINAPI
DOMMouseEvent_get_screenX(IDOMMouseEvent
*iface
, LONG
*p
)
1325 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1329 TRACE("(%p)->(%p)\n", This
, p
);
1331 nsres
= nsIDOMMouseEvent_GetScreenX(This
->mouse_event
, &screen_x
);
1332 if(NS_FAILED(nsres
))
1339 static HRESULT WINAPI
DOMMouseEvent_get_screenY(IDOMMouseEvent
*iface
, LONG
*p
)
1341 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1345 TRACE("(%p)->(%p)\n", This
, p
);
1347 nsres
= nsIDOMMouseEvent_GetScreenY(This
->mouse_event
, &screen_y
);
1348 if(NS_FAILED(nsres
))
1355 static HRESULT WINAPI
DOMMouseEvent_get_clientX(IDOMMouseEvent
*iface
, LONG
*p
)
1357 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1361 TRACE("(%p)->(%p)\n", This
, p
);
1363 nsres
= nsIDOMMouseEvent_GetClientX(This
->mouse_event
, &client_x
);
1364 if(NS_FAILED(nsres
))
1371 static HRESULT WINAPI
DOMMouseEvent_get_clientY(IDOMMouseEvent
*iface
, LONG
*p
)
1373 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1377 TRACE("(%p)->(%p)\n", This
, p
);
1379 nsres
= nsIDOMMouseEvent_GetClientY(This
->mouse_event
, &client_y
);
1380 if(NS_FAILED(nsres
))
1387 static HRESULT WINAPI
DOMMouseEvent_get_ctrlKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1389 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1393 TRACE("(%p)->(%p)\n", This
, p
);
1395 nsres
= nsIDOMMouseEvent_GetCtrlKey(This
->mouse_event
, &r
);
1396 if(NS_FAILED(nsres
))
1399 *p
= variant_bool(r
);
1403 static HRESULT WINAPI
DOMMouseEvent_get_shiftKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1405 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1409 TRACE("(%p)->(%p)\n", This
, p
);
1411 nsres
= nsIDOMMouseEvent_GetShiftKey(This
->mouse_event
, &r
);
1412 if(NS_FAILED(nsres
))
1415 *p
= variant_bool(r
);
1419 static HRESULT WINAPI
DOMMouseEvent_get_altKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1421 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1425 TRACE("(%p)->(%p)\n", This
, p
);
1427 nsres
= nsIDOMMouseEvent_GetAltKey(This
->mouse_event
, &r
);
1428 if(NS_FAILED(nsres
))
1431 *p
= variant_bool(r
);
1435 static HRESULT WINAPI
DOMMouseEvent_get_metaKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1437 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1441 TRACE("(%p)->(%p)\n", This
, p
);
1443 nsres
= nsIDOMMouseEvent_GetMetaKey(This
->mouse_event
, &r
);
1444 if(NS_FAILED(nsres
))
1447 *p
= variant_bool(r
);
1451 static HRESULT WINAPI
DOMMouseEvent_get_button(IDOMMouseEvent
*iface
, USHORT
*p
)
1453 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1457 TRACE("(%p)->(%p)\n", This
, p
);
1459 nsres
= nsIDOMMouseEvent_GetButton(This
->mouse_event
, &r
);
1460 if(NS_FAILED(nsres
))
1467 static HRESULT WINAPI
DOMMouseEvent_get_relatedTarget(IDOMMouseEvent
*iface
, IEventTarget
**p
)
1469 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1470 nsIDOMEventTarget
*related_target
;
1471 nsIDOMNode
*target_node
;
1476 TRACE("(%p)->(%p)\n", This
, p
);
1478 nsres
= nsIDOMMouseEvent_GetRelatedTarget(This
->mouse_event
, &related_target
);
1479 if(NS_FAILED(nsres
))
1482 if(!related_target
) {
1487 nsres
= nsIDOMEventTarget_QueryInterface(related_target
, &IID_nsIDOMNode
, (void**)&target_node
);
1488 nsIDOMEventTarget_Release(related_target
);
1489 if(NS_FAILED(nsres
)) {
1490 FIXME("Only node targets supported\n");
1494 hres
= get_node(target_node
, TRUE
, &node
);
1495 nsIDOMNode_Release(target_node
);
1499 *p
= &node
->event_target
.IEventTarget_iface
;
1503 static HRESULT WINAPI
DOMMouseEvent_initMouseEvent(IDOMMouseEvent
*iface
, BSTR type
,
1504 VARIANT_BOOL can_bubble
, VARIANT_BOOL cancelable
, IHTMLWindow2
*view
, LONG detail
,
1505 LONG screen_x
, LONG screen_y
, LONG client_x
, LONG client_y
, VARIANT_BOOL ctrl_key
,
1506 VARIANT_BOOL alt_key
, VARIANT_BOOL shift_key
, VARIANT_BOOL meta_key
, USHORT button
,
1507 IEventTarget
*related_target
)
1509 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1510 nsIDOMEventTarget
*nstarget
= NULL
;
1515 TRACE("(%p)->(%s %x %x %p %ld %ld %ld %ld %ld %x %x %x %x %u %p)\n", This
, debugstr_w(type
),
1516 can_bubble
, cancelable
, view
, detail
, screen_x
, screen_y
, client_x
, client_y
,
1517 ctrl_key
, alt_key
, shift_key
, meta_key
, button
, related_target
);
1520 TRACE("called on already dispatched event\n");
1525 FIXME("view argument is not supported\n");
1527 if(related_target
) {
1528 hres
= get_gecko_target(related_target
, &nstarget
);
1533 hres
= IDOMEvent_initEvent(&This
->IDOMEvent_iface
, type
, can_bubble
, cancelable
);
1534 if(SUCCEEDED(hres
)) {
1535 nsAString_InitDepend(&type_str
, type
);
1536 nsres
= nsIDOMMouseEvent_InitMouseEvent(This
->mouse_event
, &type_str
, can_bubble
, cancelable
,
1537 NULL
/* FIXME */, detail
, screen_x
, screen_y
,
1538 client_x
, client_y
, !!ctrl_key
, !!alt_key
, !!shift_key
,
1539 !!meta_key
, button
, nstarget
);
1540 nsAString_Finish(&type_str
);
1541 if(NS_FAILED(nsres
)) {
1542 FIXME("InitMouseEvent failed: %08lx\n", nsres
);
1548 nsIDOMEventTarget_Release(nstarget
);
1552 static HRESULT WINAPI
DOMMouseEvent_getModifierState(IDOMMouseEvent
*iface
, BSTR key
,
1553 VARIANT_BOOL
*activated
)
1555 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1556 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(key
), activated
);
1560 static HRESULT WINAPI
DOMMouseEvent_get_buttons(IDOMMouseEvent
*iface
, USHORT
*p
)
1562 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1566 TRACE("(%p)->(%p)\n", This
, p
);
1568 nsres
= nsIDOMMouseEvent_GetButtons(This
->mouse_event
, &r
);
1569 if(NS_FAILED(nsres
))
1576 static HRESULT WINAPI
DOMMouseEvent_get_fromElement(IDOMMouseEvent
*iface
, IHTMLElement
**p
)
1578 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1579 IEventTarget
*related_target
= NULL
;
1581 TRACE("(%p)->(%p)\n", This
, p
);
1583 if(This
->event_id
!= EVENTID_LAST
) {
1584 HRESULT hres
= S_OK
;
1585 if(event_info
[This
->event_id
].flags
& EVENT_MOUSE_FROM_RELATED
)
1586 hres
= IDOMMouseEvent_get_relatedTarget(&This
->IDOMMouseEvent_iface
, &related_target
);
1587 else if(event_info
[This
->event_id
].flags
& EVENT_MOUSE_TO_RELATED
)
1588 hres
= IDOMEvent_get_target(&This
->IDOMEvent_iface
, &related_target
);
1593 if(!related_target
) {
1598 IEventTarget_QueryInterface(related_target
, &IID_IHTMLElement
, (void**)p
);
1602 static HRESULT WINAPI
DOMMouseEvent_get_toElement(IDOMMouseEvent
*iface
, IHTMLElement
**p
)
1604 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1605 IEventTarget
*related_target
= NULL
;
1607 TRACE("(%p)->(%p)\n", This
, p
);
1609 if(This
->event_id
!= EVENTID_LAST
) {
1610 HRESULT hres
= S_OK
;
1611 if(event_info
[This
->event_id
].flags
& EVENT_MOUSE_TO_RELATED
)
1612 hres
= IDOMMouseEvent_get_relatedTarget(&This
->IDOMMouseEvent_iface
, &related_target
);
1613 else if(event_info
[This
->event_id
].flags
& EVENT_MOUSE_FROM_RELATED
)
1614 hres
= IDOMEvent_get_target(&This
->IDOMEvent_iface
, &related_target
);
1619 if(!related_target
) {
1624 IEventTarget_QueryInterface(related_target
, &IID_IHTMLElement
, (void**)p
);
1628 static HRESULT WINAPI
DOMMouseEvent_get_x(IDOMMouseEvent
*iface
, LONG
*p
)
1630 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1631 FIXME("(%p)->(%p)\n", This
, p
);
1635 static HRESULT WINAPI
DOMMouseEvent_get_y(IDOMMouseEvent
*iface
, LONG
*p
)
1637 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1638 FIXME("(%p)->(%p)\n", This
, p
);
1642 static HRESULT WINAPI
DOMMouseEvent_get_offsetX(IDOMMouseEvent
*iface
, LONG
*p
)
1644 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1646 FIXME("(%p)->(%p) returning 0\n", This
, p
);
1652 static HRESULT WINAPI
DOMMouseEvent_get_offsetY(IDOMMouseEvent
*iface
, LONG
*p
)
1654 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1656 FIXME("(%p)->(%p) returning 0\n", This
, p
);
1662 static HRESULT WINAPI
DOMMouseEvent_get_pageX(IDOMMouseEvent
*iface
, LONG
*p
)
1664 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1668 TRACE("(%p)->(%p)\n", This
, p
);
1670 nsres
= nsIDOMMouseEvent_GetPageX(This
->mouse_event
, &r
);
1671 if(NS_FAILED(nsres
))
1678 static HRESULT WINAPI
DOMMouseEvent_get_pageY(IDOMMouseEvent
*iface
, LONG
*p
)
1680 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1684 TRACE("(%p)->(%p)\n", This
, p
);
1686 nsres
= nsIDOMMouseEvent_GetPageY(This
->mouse_event
, &r
);
1687 if(NS_FAILED(nsres
))
1694 static HRESULT WINAPI
DOMMouseEvent_get_layerX(IDOMMouseEvent
*iface
, LONG
*p
)
1696 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1700 TRACE("(%p)->(%p)\n", This
, p
);
1702 nsres
= nsIDOMMouseEvent_GetLayerX(This
->mouse_event
, &r
);
1703 if(NS_FAILED(nsres
))
1710 static HRESULT WINAPI
DOMMouseEvent_get_layerY(IDOMMouseEvent
*iface
, LONG
*p
)
1712 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1716 TRACE("(%p)->(%p)\n", This
, p
);
1718 nsres
= nsIDOMMouseEvent_GetLayerY(This
->mouse_event
, &r
);
1719 if(NS_FAILED(nsres
))
1726 static HRESULT WINAPI
DOMMouseEvent_get_which(IDOMMouseEvent
*iface
, USHORT
*p
)
1728 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1732 TRACE("(%p)->(%p)\n", This
, p
);
1734 nsres
= nsIDOMMouseEvent_GetWhich(This
->mouse_event
, &r
);
1735 if(NS_FAILED(nsres
))
1742 static const IDOMMouseEventVtbl DOMMouseEventVtbl
= {
1743 DOMMouseEvent_QueryInterface
,
1744 DOMMouseEvent_AddRef
,
1745 DOMMouseEvent_Release
,
1746 DOMMouseEvent_GetTypeInfoCount
,
1747 DOMMouseEvent_GetTypeInfo
,
1748 DOMMouseEvent_GetIDsOfNames
,
1749 DOMMouseEvent_Invoke
,
1750 DOMMouseEvent_get_screenX
,
1751 DOMMouseEvent_get_screenY
,
1752 DOMMouseEvent_get_clientX
,
1753 DOMMouseEvent_get_clientY
,
1754 DOMMouseEvent_get_ctrlKey
,
1755 DOMMouseEvent_get_shiftKey
,
1756 DOMMouseEvent_get_altKey
,
1757 DOMMouseEvent_get_metaKey
,
1758 DOMMouseEvent_get_button
,
1759 DOMMouseEvent_get_relatedTarget
,
1760 DOMMouseEvent_initMouseEvent
,
1761 DOMMouseEvent_getModifierState
,
1762 DOMMouseEvent_get_buttons
,
1763 DOMMouseEvent_get_fromElement
,
1764 DOMMouseEvent_get_toElement
,
1765 DOMMouseEvent_get_x
,
1766 DOMMouseEvent_get_y
,
1767 DOMMouseEvent_get_offsetX
,
1768 DOMMouseEvent_get_offsetY
,
1769 DOMMouseEvent_get_pageX
,
1770 DOMMouseEvent_get_pageY
,
1771 DOMMouseEvent_get_layerX
,
1772 DOMMouseEvent_get_layerY
,
1773 DOMMouseEvent_get_which
1776 static inline DOMEvent
*impl_from_IDOMKeyboardEvent(IDOMKeyboardEvent
*iface
)
1778 return CONTAINING_RECORD(iface
, DOMEvent
, IDOMKeyboardEvent_iface
);
1781 static HRESULT WINAPI
DOMKeyboardEvent_QueryInterface(IDOMKeyboardEvent
*iface
, REFIID riid
, void **ppv
)
1783 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1784 return IDOMEvent_QueryInterface(&This
->IDOMEvent_iface
, riid
, ppv
);
1787 static ULONG WINAPI
DOMKeyboardEvent_AddRef(IDOMKeyboardEvent
*iface
)
1789 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1790 return IDOMEvent_AddRef(&This
->IDOMEvent_iface
);
1793 static ULONG WINAPI
DOMKeyboardEvent_Release(IDOMKeyboardEvent
*iface
)
1795 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1796 return IDOMEvent_Release(&This
->IDOMEvent_iface
);
1799 static HRESULT WINAPI
DOMKeyboardEvent_GetTypeInfoCount(IDOMKeyboardEvent
*iface
, UINT
*pctinfo
)
1801 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1802 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
1805 static HRESULT WINAPI
DOMKeyboardEvent_GetTypeInfo(IDOMKeyboardEvent
*iface
, UINT iTInfo
,
1806 LCID lcid
, ITypeInfo
**ppTInfo
)
1808 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1809 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1812 static HRESULT WINAPI
DOMKeyboardEvent_GetIDsOfNames(IDOMKeyboardEvent
*iface
, REFIID riid
,
1813 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1815 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1816 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1820 static HRESULT WINAPI
DOMKeyboardEvent_Invoke(IDOMKeyboardEvent
*iface
, DISPID dispIdMember
,
1821 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1822 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1824 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1825 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1826 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1829 static HRESULT WINAPI
DOMKeyboardEvent_get_key(IDOMKeyboardEvent
*iface
, BSTR
*p
)
1831 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1835 TRACE("(%p)->(%p)\n", This
, p
);
1838 nsAString_Init(&key_str
, NULL
);
1839 nsres
= nsIDOMKeyEvent_GetKey(This
->keyboard_event
, &key_str
);
1840 return return_nsstr(nsres
, &key_str
, p
);
1843 static HRESULT WINAPI
DOMKeyboardEvent_get_location(IDOMKeyboardEvent
*iface
, ULONG
*p
)
1845 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1849 TRACE("(%p)->(%p)\n", This
, p
);
1851 nsres
= nsIDOMKeyEvent_GetLocation(This
->keyboard_event
, &r
);
1852 if(NS_FAILED(nsres
))
1859 static HRESULT WINAPI
DOMKeyboardEvent_get_ctrlKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1861 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1865 TRACE("(%p)->(%p)\n", This
, p
);
1867 nsres
= nsIDOMKeyEvent_GetCtrlKey(This
->keyboard_event
, &r
);
1868 if(NS_FAILED(nsres
))
1871 *p
= variant_bool(r
);
1875 static HRESULT WINAPI
DOMKeyboardEvent_get_shiftKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1877 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1881 TRACE("(%p)->(%p)\n", This
, p
);
1883 nsres
= nsIDOMKeyEvent_GetShiftKey(This
->keyboard_event
, &r
);
1884 if(NS_FAILED(nsres
))
1887 *p
= variant_bool(r
);
1891 static HRESULT WINAPI
DOMKeyboardEvent_get_altKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1893 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1897 TRACE("(%p)->(%p)\n", This
, p
);
1899 nsres
= nsIDOMKeyEvent_GetAltKey(This
->keyboard_event
, &r
);
1900 if(NS_FAILED(nsres
))
1903 *p
= variant_bool(r
);
1907 static HRESULT WINAPI
DOMKeyboardEvent_get_metaKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1909 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1913 TRACE("(%p)->(%p)\n", This
, p
);
1915 nsres
= nsIDOMKeyEvent_GetMetaKey(This
->keyboard_event
, &r
);
1916 if(NS_FAILED(nsres
))
1919 *p
= variant_bool(r
);
1923 static HRESULT WINAPI
DOMKeyboardEvent_get_repeat(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1925 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1929 TRACE("(%p)->(%p)\n", This
, p
);
1931 nsres
= nsIDOMKeyEvent_GetRepeat(This
->keyboard_event
, &r
);
1932 if(NS_FAILED(nsres
))
1935 *p
= variant_bool(r
);
1939 static HRESULT WINAPI
DOMKeyboardEvent_getModifierState(IDOMKeyboardEvent
*iface
, BSTR key
,
1940 VARIANT_BOOL
*state
)
1942 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1943 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(key
), state
);
1947 static HRESULT WINAPI
DOMKeyboardEvent_initKeyboardEvent(IDOMKeyboardEvent
*iface
, BSTR type
,
1948 VARIANT_BOOL can_bubble
, VARIANT_BOOL cancelable
, IHTMLWindow2
*view
, BSTR key
,
1949 ULONG location
, BSTR modifiers_list
, VARIANT_BOOL repeat
, BSTR locale
)
1951 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1952 FIXME("(%p)->(%s %x %x %p %s %lu %s %x %s)\n", This
, debugstr_w(type
), can_bubble
,
1953 cancelable
, view
, debugstr_w(key
), location
, debugstr_w(modifiers_list
),
1954 repeat
, debugstr_w(locale
));
1958 static HRESULT WINAPI
DOMKeyboardEvent_get_keyCode(IDOMKeyboardEvent
*iface
, LONG
*p
)
1960 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1964 TRACE("(%p)->(%p)\n", This
, p
);
1966 nsres
= nsIDOMKeyEvent_GetKeyCode(This
->keyboard_event
, &r
);
1967 if(NS_FAILED(nsres
))
1974 static HRESULT WINAPI
DOMKeyboardEvent_get_charCode(IDOMKeyboardEvent
*iface
, LONG
*p
)
1976 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1980 TRACE("(%p)->(%p)\n", This
, p
);
1982 nsres
= nsIDOMKeyEvent_GetKeyCode(This
->keyboard_event
, &r
);
1983 if(NS_FAILED(nsres
))
1990 static HRESULT WINAPI
DOMKeyboardEvent_get_which(IDOMKeyboardEvent
*iface
, LONG
*p
)
1992 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1996 TRACE("(%p)->(%p)\n", This
, p
);
1998 nsres
= nsIDOMKeyEvent_GetWhich(This
->keyboard_event
, &r
);
1999 if(NS_FAILED(nsres
))
2006 static HRESULT WINAPI
DOMKeyboardEvent_get_char(IDOMKeyboardEvent
*iface
, VARIANT
*p
)
2008 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2009 FIXME("(%p)->(%p)\n", This
, p
);
2013 static HRESULT WINAPI
DOMKeyboardEvent_get_locale(IDOMKeyboardEvent
*iface
, BSTR
*p
)
2015 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2016 FIXME("(%p)->(%p)\n", This
, p
);
2020 static const IDOMKeyboardEventVtbl DOMKeyboardEventVtbl
= {
2021 DOMKeyboardEvent_QueryInterface
,
2022 DOMKeyboardEvent_AddRef
,
2023 DOMKeyboardEvent_Release
,
2024 DOMKeyboardEvent_GetTypeInfoCount
,
2025 DOMKeyboardEvent_GetTypeInfo
,
2026 DOMKeyboardEvent_GetIDsOfNames
,
2027 DOMKeyboardEvent_Invoke
,
2028 DOMKeyboardEvent_get_key
,
2029 DOMKeyboardEvent_get_location
,
2030 DOMKeyboardEvent_get_ctrlKey
,
2031 DOMKeyboardEvent_get_shiftKey
,
2032 DOMKeyboardEvent_get_altKey
,
2033 DOMKeyboardEvent_get_metaKey
,
2034 DOMKeyboardEvent_get_repeat
,
2035 DOMKeyboardEvent_getModifierState
,
2036 DOMKeyboardEvent_initKeyboardEvent
,
2037 DOMKeyboardEvent_get_keyCode
,
2038 DOMKeyboardEvent_get_charCode
,
2039 DOMKeyboardEvent_get_which
,
2040 DOMKeyboardEvent_get_char
,
2041 DOMKeyboardEvent_get_locale
2046 IDOMCustomEvent IDOMCustomEvent_iface
;
2050 static inline DOMCustomEvent
*impl_from_IDOMCustomEvent(IDOMCustomEvent
*iface
)
2052 return CONTAINING_RECORD(iface
, DOMCustomEvent
, IDOMCustomEvent_iface
);
2055 static HRESULT WINAPI
DOMCustomEvent_QueryInterface(IDOMCustomEvent
*iface
, REFIID riid
, void **ppv
)
2057 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2058 return IDOMEvent_QueryInterface(&This
->event
.IDOMEvent_iface
, riid
, ppv
);
2061 static ULONG WINAPI
DOMCustomEvent_AddRef(IDOMCustomEvent
*iface
)
2063 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2064 return IDOMEvent_AddRef(&This
->event
.IDOMEvent_iface
);
2067 static ULONG WINAPI
DOMCustomEvent_Release(IDOMCustomEvent
*iface
)
2069 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2070 return IDOMEvent_Release(&This
->event
.IDOMEvent_iface
);
2073 static HRESULT WINAPI
DOMCustomEvent_GetTypeInfoCount(IDOMCustomEvent
*iface
, UINT
*pctinfo
)
2075 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2076 return IDispatchEx_GetTypeInfoCount(&This
->event
.dispex
.IDispatchEx_iface
, pctinfo
);
2079 static HRESULT WINAPI
DOMCustomEvent_GetTypeInfo(IDOMCustomEvent
*iface
, UINT iTInfo
,
2080 LCID lcid
, ITypeInfo
**ppTInfo
)
2082 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2083 return IDispatchEx_GetTypeInfo(&This
->event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
2086 static HRESULT WINAPI
DOMCustomEvent_GetIDsOfNames(IDOMCustomEvent
*iface
, REFIID riid
,
2087 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2089 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2090 return IDispatchEx_GetIDsOfNames(&This
->event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
2094 static HRESULT WINAPI
DOMCustomEvent_Invoke(IDOMCustomEvent
*iface
, DISPID dispIdMember
,
2095 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2096 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2098 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2099 return IDispatchEx_Invoke(&This
->event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
2100 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2103 static HRESULT WINAPI
DOMCustomEvent_get_detail(IDOMCustomEvent
*iface
, VARIANT
*p
)
2105 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2107 TRACE("(%p)->(%p)\n", This
, p
);
2110 return VariantCopy(p
, &This
->detail
);
2113 static HRESULT WINAPI
DOMCustomEvent_initCustomEvent(IDOMCustomEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
2114 VARIANT_BOOL cancelable
, VARIANT
*detail
)
2116 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2119 TRACE("(%p)->(%s %x %x %s)\n", This
, debugstr_w(type
), can_bubble
, cancelable
, debugstr_variant(detail
));
2121 hres
= IDOMEvent_initEvent(&This
->event
.IDOMEvent_iface
, type
, can_bubble
, cancelable
);
2125 return VariantCopy(&This
->detail
, detail
);
2128 static const IDOMCustomEventVtbl DOMCustomEventVtbl
= {
2129 DOMCustomEvent_QueryInterface
,
2130 DOMCustomEvent_AddRef
,
2131 DOMCustomEvent_Release
,
2132 DOMCustomEvent_GetTypeInfoCount
,
2133 DOMCustomEvent_GetTypeInfo
,
2134 DOMCustomEvent_GetIDsOfNames
,
2135 DOMCustomEvent_Invoke
,
2136 DOMCustomEvent_get_detail
,
2137 DOMCustomEvent_initCustomEvent
2140 static DOMCustomEvent
*DOMCustomEvent_from_DOMEvent(DOMEvent
*event
)
2142 return CONTAINING_RECORD(event
, DOMCustomEvent
, event
);
2145 static void *DOMCustomEvent_query_interface(DOMEvent
*event
, REFIID riid
)
2147 DOMCustomEvent
*custom_event
= DOMCustomEvent_from_DOMEvent(event
);
2148 if(IsEqualGUID(&IID_IDOMCustomEvent
, riid
))
2149 return &custom_event
->IDOMCustomEvent_iface
;
2153 static void DOMCustomEvent_destroy(DOMEvent
*event
)
2155 DOMCustomEvent
*custom_event
= DOMCustomEvent_from_DOMEvent(event
);
2156 VariantClear(&custom_event
->detail
);
2161 IDOMMessageEvent IDOMMessageEvent_iface
;
2165 static inline DOMMessageEvent
*impl_from_IDOMMessageEvent(IDOMMessageEvent
*iface
)
2167 return CONTAINING_RECORD(iface
, DOMMessageEvent
, IDOMMessageEvent_iface
);
2170 static HRESULT WINAPI
DOMMessageEvent_QueryInterface(IDOMMessageEvent
*iface
, REFIID riid
, void **ppv
)
2172 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2173 return IDOMEvent_QueryInterface(&This
->event
.IDOMEvent_iface
, riid
, ppv
);
2176 static ULONG WINAPI
DOMMessageEvent_AddRef(IDOMMessageEvent
*iface
)
2178 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2179 return IDOMEvent_AddRef(&This
->event
.IDOMEvent_iface
);
2182 static ULONG WINAPI
DOMMessageEvent_Release(IDOMMessageEvent
*iface
)
2184 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2185 return IDOMEvent_Release(&This
->event
.IDOMEvent_iface
);
2188 static HRESULT WINAPI
DOMMessageEvent_GetTypeInfoCount(IDOMMessageEvent
*iface
, UINT
*pctinfo
)
2190 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2191 return IDispatchEx_GetTypeInfoCount(&This
->event
.dispex
.IDispatchEx_iface
, pctinfo
);
2194 static HRESULT WINAPI
DOMMessageEvent_GetTypeInfo(IDOMMessageEvent
*iface
, UINT iTInfo
,
2195 LCID lcid
, ITypeInfo
**ppTInfo
)
2197 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2198 return IDispatchEx_GetTypeInfo(&This
->event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
2201 static HRESULT WINAPI
DOMMessageEvent_GetIDsOfNames(IDOMMessageEvent
*iface
, REFIID riid
,
2202 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2204 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2205 return IDispatchEx_GetIDsOfNames(&This
->event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
2209 static HRESULT WINAPI
DOMMessageEvent_Invoke(IDOMMessageEvent
*iface
, DISPID dispIdMember
,
2210 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2211 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2213 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2214 return IDispatchEx_Invoke(&This
->event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
2215 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2218 static HRESULT WINAPI
DOMMessageEvent_get_data(IDOMMessageEvent
*iface
, BSTR
*p
)
2220 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2222 TRACE("(%p)->(%p)\n", This
, p
);
2224 return (*p
= SysAllocString(This
->data
)) ? S_OK
: E_OUTOFMEMORY
;
2227 static HRESULT WINAPI
DOMMessageEvent_get_origin(IDOMMessageEvent
*iface
, BSTR
*p
)
2229 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2230 FIXME("(%p)->(%p)\n", This
, p
);
2234 static HRESULT WINAPI
DOMMessageEvent_get_source(IDOMMessageEvent
*iface
, IHTMLWindow2
**p
)
2236 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2237 FIXME("(%p)->(%p)\n", This
, p
);
2241 static HRESULT WINAPI
DOMMessageEvent_initMessageEvent(IDOMMessageEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
2242 VARIANT_BOOL cancelable
, BSTR data
, BSTR origin
,
2243 BSTR last_event_id
, IHTMLWindow2
*source
)
2245 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2246 FIXME("(%p)->(%s %x %x %s %s %s %p)\n", This
, debugstr_w(type
), can_bubble
, cancelable
,
2247 debugstr_w(data
), debugstr_w(origin
), debugstr_w(last_event_id
), source
);
2251 static const IDOMMessageEventVtbl DOMMessageEventVtbl
= {
2252 DOMMessageEvent_QueryInterface
,
2253 DOMMessageEvent_AddRef
,
2254 DOMMessageEvent_Release
,
2255 DOMMessageEvent_GetTypeInfoCount
,
2256 DOMMessageEvent_GetTypeInfo
,
2257 DOMMessageEvent_GetIDsOfNames
,
2258 DOMMessageEvent_Invoke
,
2259 DOMMessageEvent_get_data
,
2260 DOMMessageEvent_get_origin
,
2261 DOMMessageEvent_get_source
,
2262 DOMMessageEvent_initMessageEvent
2265 static DOMMessageEvent
*DOMMessageEvent_from_DOMEvent(DOMEvent
*event
)
2267 return CONTAINING_RECORD(event
, DOMMessageEvent
, event
);
2270 static void *DOMMessageEvent_query_interface(DOMEvent
*event
, REFIID riid
)
2272 DOMMessageEvent
*message_event
= DOMMessageEvent_from_DOMEvent(event
);
2273 if(IsEqualGUID(&IID_IDOMMessageEvent
, riid
))
2274 return &message_event
->IDOMMessageEvent_iface
;
2278 static void DOMMessageEvent_destroy(DOMEvent
*event
)
2280 DOMMessageEvent
*message_event
= DOMMessageEvent_from_DOMEvent(event
);
2281 heap_free(message_event
->data
);
2284 static const tid_t DOMEvent_iface_tids
[] = {
2289 static dispex_static_data_t DOMEvent_dispex
= {
2296 static const tid_t DOMUIEvent_iface_tids
[] = {
2302 static dispex_static_data_t DOMUIEvent_dispex
= {
2306 DOMUIEvent_iface_tids
2309 static const tid_t DOMMouseEvent_iface_tids
[] = {
2316 static dispex_static_data_t DOMMouseEvent_dispex
= {
2319 DispDOMMouseEvent_tid
,
2320 DOMMouseEvent_iface_tids
2323 static const tid_t DOMKeyboardEvent_iface_tids
[] = {
2326 IDOMKeyboardEvent_tid
,
2330 static dispex_static_data_t DOMKeyboardEvent_dispex
= {
2333 DispDOMKeyboardEvent_tid
,
2334 DOMKeyboardEvent_iface_tids
2337 static const tid_t DOMCustomEvent_iface_tids
[] = {
2339 IDOMCustomEvent_tid
,
2343 static dispex_static_data_t DOMCustomEvent_dispex
= {
2346 DispDOMCustomEvent_tid
,
2347 DOMCustomEvent_iface_tids
2350 static const tid_t DOMMessageEvent_iface_tids
[] = {
2352 IDOMMessageEvent_tid
,
2356 dispex_static_data_t DOMMessageEvent_dispex
= {
2359 DispDOMMessageEvent_tid
,
2360 DOMMessageEvent_iface_tids
2363 static BOOL
check_event_iface(nsIDOMEvent
*event
, REFIID riid
)
2368 nsres
= nsIDOMEvent_QueryInterface(event
, riid
, (void**)&iface
);
2369 if(NS_FAILED(nsres
))
2372 nsISupports_Release(iface
);
2376 static DOMEvent
*alloc_event(nsIDOMEvent
*nsevent
, compat_mode_t compat_mode
, eventid_t event_id
)
2378 dispex_static_data_t
*dispex_data
= &DOMEvent_dispex
;
2379 DOMEvent
*event
= NULL
;
2382 if(check_event_iface(nsevent
, &IID_nsIDOMCustomEvent
)) {
2383 DOMCustomEvent
*custom_event
= heap_alloc_zero(sizeof(*custom_event
));
2387 custom_event
->IDOMCustomEvent_iface
.lpVtbl
= &DOMCustomEventVtbl
;
2388 custom_event
->event
.query_interface
= DOMCustomEvent_query_interface
;
2389 custom_event
->event
.destroy
= DOMCustomEvent_destroy
;
2390 event
= &custom_event
->event
;
2391 dispex_data
= &DOMCustomEvent_dispex
;
2392 }else if(event_id
== EVENTID_MESSAGE
) {
2393 DOMMessageEvent
*message_event
= heap_alloc_zero(sizeof(*message_event
));
2397 message_event
->IDOMMessageEvent_iface
.lpVtbl
= &DOMMessageEventVtbl
;
2398 message_event
->event
.query_interface
= DOMMessageEvent_query_interface
;
2399 message_event
->event
.destroy
= DOMMessageEvent_destroy
;
2400 event
= &message_event
->event
;
2401 dispex_data
= &DOMMessageEvent_dispex
;
2403 event
= heap_alloc_zero(sizeof(*event
));
2408 event
->IDOMEvent_iface
.lpVtbl
= &DOMEventVtbl
;
2409 event
->IDOMUIEvent_iface
.lpVtbl
= &DOMUIEventVtbl
;
2410 event
->IDOMMouseEvent_iface
.lpVtbl
= &DOMMouseEventVtbl
;
2411 event
->IDOMKeyboardEvent_iface
.lpVtbl
= &DOMKeyboardEventVtbl
;
2413 event
->event_id
= event_id
;
2414 if(event_id
!= EVENTID_LAST
) {
2415 event
->type
= heap_strdupW(event_info
[event_id
].name
);
2420 event
->bubbles
= (event_info
[event_id
].flags
& EVENT_BUBBLES
) != 0;
2421 event
->cancelable
= (event_info
[event_id
].flags
& EVENT_CANCELABLE
) != 0;
2423 nsIDOMEvent_AddRef(event
->nsevent
= nsevent
);
2425 event
->time_stamp
= get_time_stamp();
2427 nsres
= nsIDOMEvent_QueryInterface(nsevent
, &IID_nsIDOMUIEvent
, (void**)&event
->ui_event
);
2428 if(NS_SUCCEEDED(nsres
))
2429 dispex_data
= &DOMUIEvent_dispex
;
2431 event
->ui_event
= NULL
;
2433 nsres
= nsIDOMEvent_QueryInterface(nsevent
, &IID_nsIDOMMouseEvent
, (void**)&event
->mouse_event
);
2434 if(NS_SUCCEEDED(nsres
))
2435 dispex_data
= &DOMMouseEvent_dispex
;
2437 event
->mouse_event
= NULL
;
2439 nsres
= nsIDOMEvent_QueryInterface(nsevent
, &IID_nsIDOMKeyEvent
, (void**)&event
->keyboard_event
);
2440 if(NS_SUCCEEDED(nsres
))
2441 dispex_data
= &DOMKeyboardEvent_dispex
;
2443 event
->keyboard_event
= NULL
;
2445 init_dispatch(&event
->dispex
, (IUnknown
*)&event
->IDOMEvent_iface
, dispex_data
, compat_mode
);
2449 HRESULT
create_event_from_nsevent(nsIDOMEvent
*nsevent
, compat_mode_t compat_mode
, DOMEvent
**ret_event
)
2451 eventid_t event_id
= EVENTID_LAST
;
2456 nsAString_Init(&nsstr
, NULL
);
2457 nsres
= nsIDOMEvent_GetType(nsevent
, &nsstr
);
2458 if(NS_SUCCEEDED(nsres
)) {
2460 nsAString_GetData(&nsstr
, &type
);
2461 event_id
= str_to_eid(type
);
2462 if(event_id
== EVENTID_LAST
)
2463 FIXME("unknown event type %s\n", debugstr_w(type
));
2465 ERR("GetType failed: %08lx\n", nsres
);
2467 nsAString_Finish(&nsstr
);
2469 event
= alloc_event(nsevent
, compat_mode
, event_id
);
2471 return E_OUTOFMEMORY
;
2473 event
->trusted
= TRUE
;
2478 HRESULT
create_document_event_str(HTMLDocumentNode
*doc
, const WCHAR
*type
, IDOMEvent
**ret_event
)
2480 nsIDOMEvent
*nsevent
;
2485 nsAString_InitDepend(&nsstr
, type
);
2486 nsres
= nsIDOMHTMLDocument_CreateEvent(doc
->nsdoc
, &nsstr
, &nsevent
);
2487 nsAString_Finish(&nsstr
);
2488 if(NS_FAILED(nsres
)) {
2489 FIXME("CreateEvent(%s) failed: %08lx\n", debugstr_w(type
), nsres
);
2493 event
= alloc_event(nsevent
, dispex_compat_mode(&doc
->node
.event_target
.dispex
), EVENTID_LAST
);
2494 nsIDOMEvent_Release(nsevent
);
2496 return E_OUTOFMEMORY
;
2498 *ret_event
= &event
->IDOMEvent_iface
;
2502 HRESULT
create_document_event(HTMLDocumentNode
*doc
, eventid_t event_id
, DOMEvent
**ret_event
)
2504 nsIDOMEvent
*nsevent
;
2509 nsAString_InitDepend(&nsstr
, event_types
[event_info
[event_id
].type
]);
2510 nsres
= nsIDOMHTMLDocument_CreateEvent(doc
->nsdoc
, &nsstr
, &nsevent
);
2511 nsAString_Finish(&nsstr
);
2512 if(NS_FAILED(nsres
)) {
2513 FIXME("CreateEvent(%s) failed: %08lx\n", debugstr_w(event_types
[event_info
[event_id
].type
]), nsres
);
2517 event
= alloc_event(nsevent
, doc
->document_mode
, event_id
);
2519 return E_OUTOFMEMORY
;
2521 event
->event_id
= event_id
;
2522 event
->trusted
= TRUE
;
2527 HRESULT
create_message_event(HTMLDocumentNode
*doc
, BSTR data
, DOMEvent
**ret
)
2529 DOMMessageEvent
*message_event
;
2533 hres
= create_document_event(doc
, EVENTID_MESSAGE
, &event
);
2536 message_event
= DOMMessageEvent_from_DOMEvent(event
);
2538 if(!(message_event
->data
= heap_strdupW(data
))) {
2539 IDOMEvent_Release(&event
->IDOMEvent_iface
);
2540 return E_OUTOFMEMORY
;
2547 static HRESULT
call_disp_func(IDispatch
*disp
, DISPPARAMS
*dp
, VARIANT
*retv
)
2549 IDispatchEx
*dispex
;
2553 memset(&ei
, 0, sizeof(ei
));
2555 hres
= IDispatch_QueryInterface(disp
, &IID_IDispatchEx
, (void**)&dispex
);
2556 if(SUCCEEDED(hres
)) {
2557 hres
= IDispatchEx_InvokeEx(dispex
, 0, GetUserDefaultLCID(), DISPATCH_METHOD
, dp
, retv
, &ei
, NULL
);
2558 IDispatchEx_Release(dispex
);
2560 TRACE("Could not get IDispatchEx interface: %08lx\n", hres
);
2561 hres
= IDispatch_Invoke(disp
, 0, &IID_NULL
, GetUserDefaultLCID(), DISPATCH_METHOD
,
2562 dp
, retv
, &ei
, NULL
);
2568 static HRESULT
call_cp_func(IDispatch
*disp
, DISPID dispid
, IHTMLEventObj
*event_obj
, VARIANT
*retv
)
2570 DISPPARAMS dp
= {NULL
,NULL
,0,0};
2575 TRACE("%p,%ld,%p,%p\n", disp
, dispid
, event_obj
, retv
);
2578 V_VT(&event_arg
) = VT_DISPATCH
;
2579 V_DISPATCH(&event_arg
) = (IDispatch
*)event_obj
;
2580 dp
.rgvarg
= &event_arg
;
2584 memset(&ei
, 0, sizeof(ei
));
2585 return IDispatch_Invoke(disp
, dispid
, &IID_NULL
, 0, DISPATCH_METHOD
, &dp
, retv
, &ei
, &argerr
);
2588 static BOOL
use_event_quirks(EventTarget
*event_target
)
2590 return dispex_compat_mode(&event_target
->dispex
) < COMPAT_MODE_IE9
;
2593 static BOOL
is_cp_event(cp_static_data_t
*data
, DISPID dispid
)
2598 if(!data
|| dispid
== DISPID_UNKNOWN
)
2602 hres
= get_dispids(data
->tid
, &data
->id_cnt
, &data
->ids
);
2608 max
= data
->id_cnt
-1;
2611 if(data
->ids
[i
] == dispid
)
2614 if(data
->ids
[i
] < dispid
)
2623 static void call_event_handlers(EventTarget
*event_target
, DOMEvent
*event
, dispatch_mode_t dispatch_mode
)
2625 const listener_container_t
*container
= get_listener_container(event_target
, event
->type
, FALSE
);
2626 event_listener_t
*listener
, listeners_buf
[8], *listeners
= listeners_buf
;
2627 unsigned listeners_cnt
, listeners_size
;
2628 ConnectionPointContainer
*cp_container
= NULL
;
2629 const event_target_vtbl_t
*vtbl
= NULL
;
2630 BOOL skip_onevent_listener
= FALSE
;
2634 assert(!event
->current_target
);
2635 event
->current_target
= event_target
;
2637 if(container
&& !list_empty(&container
->listeners
) && event
->phase
!= DEP_CAPTURING_PHASE
) {
2638 listener
= LIST_ENTRY(list_tail(&container
->listeners
), event_listener_t
, entry
);
2639 if(listener
&& listener
->function
&& listener
->type
== LISTENER_TYPE_ONEVENT
2640 && use_event_quirks(event_target
)) {
2641 DISPID named_arg
= DISPID_THIS
;
2643 DISPPARAMS dp
= {&arg
, &named_arg
, 1, 1};
2645 skip_onevent_listener
= TRUE
;
2647 V_VT(&arg
) = VT_DISPATCH
;
2648 V_DISPATCH(&arg
) = (IDispatch
*)&event_target
->dispex
.IDispatchEx_iface
;
2649 V_VT(&v
) = VT_EMPTY
;
2651 TRACE("%p %s >>>\n", event_target
, debugstr_w(event
->type
));
2652 hres
= call_disp_func(listener
->function
, &dp
, &v
);
2654 TRACE("%p %s <<< %s\n", event_target
, debugstr_w(event
->type
), debugstr_variant(&v
));
2656 if(event
->cancelable
) {
2657 if(V_VT(&v
) == VT_BOOL
) {
2659 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
2660 }else if(V_VT(&v
) != VT_EMPTY
) {
2661 FIXME("unhandled result %s\n", debugstr_variant(&v
));
2666 WARN("%p %s <<< %08lx\n", event_target
, debugstr_w(event
->type
), hres
);
2672 listeners_size
= ARRAY_SIZE(listeners_buf
);
2675 LIST_FOR_EACH_ENTRY(listener
, &container
->listeners
, event_listener_t
, entry
) {
2676 if(!listener
->function
)
2678 switch(listener
->type
) {
2679 case LISTENER_TYPE_ONEVENT
:
2680 if(skip_onevent_listener
|| event
->phase
== DEP_CAPTURING_PHASE
)
2683 case LISTENER_TYPE_CAPTURE
:
2684 if(event
->phase
== DEP_BUBBLING_PHASE
|| dispatch_mode
== DISPATCH_LEGACY
)
2687 case LISTENER_TYPE_BUBBLE
:
2688 if(event
->phase
== DEP_CAPTURING_PHASE
|| dispatch_mode
== DISPATCH_LEGACY
)
2691 case LISTENER_TYPE_ATTACHED
:
2692 if(event
->phase
== DEP_CAPTURING_PHASE
|| dispatch_mode
== DISPATCH_STANDARD
)
2697 if(listeners_cnt
== listeners_size
) {
2698 event_listener_t
*new_listeners
;
2699 if(listeners
== listeners_buf
) {
2700 new_listeners
= heap_alloc(listeners_size
* 2 * sizeof(*new_listeners
));
2703 memcpy(new_listeners
, listeners
, listeners_cnt
* sizeof(*listeners
));
2705 new_listeners
= heap_realloc(listeners
, listeners_size
* 2 * sizeof(*new_listeners
));
2707 listeners
= new_listeners
;
2708 listeners_size
*= 2;
2711 listeners
[listeners_cnt
].type
= listener
->type
;
2712 IDispatch_AddRef(listeners
[listeners_cnt
].function
= listener
->function
);
2717 for(listener
= listeners
; !event
->stop_immediate_propagation
2718 && listener
< listeners
+ listeners_cnt
; listener
++) {
2719 if(listener
->type
!= LISTENER_TYPE_ATTACHED
) {
2720 DISPID named_arg
= DISPID_THIS
;
2722 DISPPARAMS dp
= {args
, &named_arg
, 2, 1};
2724 V_VT(args
) = VT_DISPATCH
;
2725 V_DISPATCH(args
) = (IDispatch
*)&event_target
->dispex
.IDispatchEx_iface
;
2726 V_VT(args
+1) = VT_DISPATCH
;
2727 V_DISPATCH(args
+1) = dispatch_mode
== DISPATCH_LEGACY
2728 ? (IDispatch
*)event
->event_obj
: (IDispatch
*)&event
->IDOMEvent_iface
;
2729 V_VT(&v
) = VT_EMPTY
;
2731 TRACE("%p %s >>>\n", event_target
, debugstr_w(event
->type
));
2732 hres
= call_disp_func(listener
->function
, &dp
, &v
);
2734 TRACE("%p %s <<< %s\n", event_target
, debugstr_w(event
->type
),
2735 debugstr_variant(&v
));
2737 if(event
->cancelable
) {
2738 if(V_VT(&v
) == VT_BOOL
) {
2740 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
2741 }else if(V_VT(&v
) != VT_EMPTY
) {
2742 FIXME("unhandled result %s\n", debugstr_variant(&v
));
2747 WARN("%p %s <<< %08lx\n", event_target
, debugstr_w(event
->type
), hres
);
2751 DISPPARAMS dp
= {&arg
, NULL
, 1, 0};
2753 V_VT(&arg
) = VT_DISPATCH
;
2754 V_DISPATCH(&arg
) = (IDispatch
*)event
->event_obj
;
2755 V_VT(&v
) = VT_EMPTY
;
2757 TRACE("%p %s attached >>>\n", event_target
, debugstr_w(event
->type
));
2758 hres
= call_disp_func(listener
->function
, &dp
, &v
);
2760 TRACE("%p %s attached <<<\n", event_target
, debugstr_w(event
->type
));
2762 if(event
->cancelable
) {
2763 if(V_VT(&v
) == VT_BOOL
) {
2765 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
2766 }else if(V_VT(&v
) != VT_EMPTY
) {
2767 FIXME("unhandled result %s\n", debugstr_variant(&v
));
2772 WARN("%p %s attached <<< %08lx\n", event_target
, debugstr_w(event
->type
), hres
);
2777 for(listener
= listeners
; listener
< listeners
+ listeners_cnt
; listener
++)
2778 IDispatch_Release(listener
->function
);
2779 if(listeners
!= listeners_buf
)
2780 heap_free(listeners
);
2782 if(event
->phase
!= DEP_CAPTURING_PHASE
&& event
->event_id
!= EVENTID_LAST
2783 && event_info
[event
->event_id
].dispid
&& (vtbl
= dispex_get_vtbl(&event_target
->dispex
))
2784 && vtbl
->get_cp_container
)
2785 cp_container
= vtbl
->get_cp_container(&event_target
->dispex
);
2787 if(cp_container
->cps
) {
2788 ConnectionPoint
*cp
;
2791 for(j
=0; cp_container
->cp_entries
[j
].riid
; j
++) {
2792 cp
= cp_container
->cps
+ j
;
2793 if(!cp
->sinks_size
|| !is_cp_event(cp
->data
, event_info
[event
->event_id
].dispid
))
2796 for(i
=0; i
< cp
->sinks_size
; i
++) {
2797 if(!cp
->sinks
[i
].disp
)
2800 V_VT(&v
) = VT_EMPTY
;
2802 TRACE("%p cp %s [%u] >>>\n", event_target
, debugstr_w(event
->type
), i
);
2803 hres
= call_cp_func(cp
->sinks
[i
].disp
, event_info
[event
->event_id
].dispid
,
2804 cp
->data
->pass_event_arg
? event
->event_obj
: NULL
, &v
);
2806 TRACE("%p cp %s [%u] <<<\n", event_target
, debugstr_w(event
->type
), i
);
2808 if(event
->cancelable
) {
2809 if(V_VT(&v
) == VT_BOOL
) {
2811 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
2812 }else if(V_VT(&v
) != VT_EMPTY
) {
2813 FIXME("unhandled result %s\n", debugstr_variant(&v
));
2818 WARN("%p cp %s [%u] <<< %08lx\n", event_target
, debugstr_w(event
->type
), i
, hres
);
2823 IConnectionPointContainer_Release(&cp_container
->IConnectionPointContainer_iface
);
2826 event
->current_target
= NULL
;
2829 static HRESULT
dispatch_event_object(EventTarget
*event_target
, DOMEvent
*event
,
2830 dispatch_mode_t dispatch_mode
, VARIANT_BOOL
*r
)
2832 EventTarget
*target_chain_buf
[8], **target_chain
= target_chain_buf
;
2833 unsigned chain_cnt
, chain_buf_size
, i
;
2834 const event_target_vtbl_t
*vtbl
, *target_vtbl
;
2835 HTMLEventObj
*event_obj_ref
= NULL
;
2836 IHTMLEventObj
*prev_event
= NULL
;
2840 TRACE("(%p) %s\n", event_target
, debugstr_w(event
->type
));
2843 FIXME("Uninitialized event.\n");
2847 if(event
->current_target
) {
2848 FIXME("event is being dispatched.\n");
2852 iter
= event_target
;
2853 IEventTarget_AddRef(&event_target
->IEventTarget_iface
);
2856 chain_buf_size
= ARRAY_SIZE(target_chain_buf
);
2859 if(chain_cnt
== chain_buf_size
) {
2860 EventTarget
**new_chain
;
2861 if(target_chain
== target_chain_buf
) {
2862 new_chain
= heap_alloc(chain_buf_size
* 2 * sizeof(*new_chain
));
2865 memcpy(new_chain
, target_chain
, chain_buf_size
* sizeof(*new_chain
));
2867 new_chain
= heap_realloc(target_chain
, chain_buf_size
* 2 * sizeof(*new_chain
));
2871 chain_buf_size
*= 2;
2872 target_chain
= new_chain
;
2875 target_chain
[chain_cnt
++] = iter
;
2877 if(!(vtbl
= dispex_get_vtbl(&iter
->dispex
)) || !vtbl
->get_parent_event_target
)
2879 iter
= vtbl
->get_parent_event_target(&iter
->dispex
);
2882 if(!event
->event_obj
&& !event
->no_event_obj
) {
2883 event_obj_ref
= alloc_event_obj(event
, dispex_compat_mode(&event
->dispex
));
2885 event
->event_obj
= &event_obj_ref
->IHTMLEventObj_iface
;
2888 target_vtbl
= dispex_get_vtbl(&event_target
->dispex
);
2889 if(target_vtbl
&& target_vtbl
->set_current_event
)
2890 prev_event
= target_vtbl
->set_current_event(&event_target
->dispex
, event
->event_obj
);
2893 IEventTarget_Release(&event
->target
->IEventTarget_iface
);
2894 event
->target
= event_target
;
2895 IEventTarget_AddRef(&event_target
->IEventTarget_iface
);
2897 event
->phase
= DEP_CAPTURING_PHASE
;
2899 while(!event
->stop_propagation
&& i
)
2900 call_event_handlers(target_chain
[i
--], event
, dispatch_mode
);
2902 if(!event
->stop_propagation
) {
2903 event
->phase
= DEP_AT_TARGET
;
2904 call_event_handlers(target_chain
[0], event
, dispatch_mode
);
2907 if(event
->bubbles
) {
2908 event
->phase
= DEP_BUBBLING_PHASE
;
2909 for(i
= 1; !event
->stop_propagation
&& i
< chain_cnt
; i
++)
2910 call_event_handlers(target_chain
[i
], event
, dispatch_mode
);
2914 *r
= variant_bool(!event
->prevent_default
);
2916 if(target_vtbl
&& target_vtbl
->set_current_event
) {
2917 prev_event
= target_vtbl
->set_current_event(&event_target
->dispex
, prev_event
);
2919 IHTMLEventObj_Release(prev_event
);
2922 if(event
->event_id
!= EVENTID_LAST
&& (event_info
[event
->event_id
].flags
& EVENT_HASDEFAULTHANDLERS
)) {
2923 BOOL prevent_default
= event
->prevent_default
;
2924 for(i
= 0; !prevent_default
&& i
< chain_cnt
; i
++) {
2925 vtbl
= dispex_get_vtbl(&target_chain
[i
]->dispex
);
2926 if(!vtbl
|| !vtbl
->handle_event_default
)
2928 hres
= vtbl
->handle_event_default(&event_target
->dispex
, event
->event_id
,
2929 event
->nsevent
, &prevent_default
);
2930 if(FAILED(hres
) || event
->stop_propagation
)
2933 nsIDOMEvent_PreventDefault(event
->nsevent
);
2937 event
->prevent_default
= FALSE
;
2939 event
->event_obj
= NULL
;
2940 IHTMLEventObj_Release(&event_obj_ref
->IHTMLEventObj_iface
);
2943 for(i
= 0; i
< chain_cnt
; i
++)
2944 IEventTarget_Release(&target_chain
[i
]->IEventTarget_iface
);
2945 if(target_chain
!= target_chain_buf
)
2946 heap_free(target_chain
);
2951 void dispatch_event(EventTarget
*event_target
, DOMEvent
*event
)
2953 dispatch_event_object(event_target
, event
, DISPATCH_BOTH
, NULL
);
2956 * We may have registered multiple Gecko listeners for the same event type,
2957 * but we already dispatched event to all relevant targets. Stop event
2958 * propagation here to avoid events being dispatched multiple times.
2960 if(event
->event_id
!= EVENTID_LAST
&& (event_info
[event
->event_id
].flags
& EVENT_BIND_TO_TARGET
))
2961 nsIDOMEvent_StopPropagation(event
->nsevent
);
2964 HRESULT
fire_event(HTMLDOMNode
*node
, const WCHAR
*event_name
, VARIANT
*event_var
, VARIANT_BOOL
*cancelled
)
2966 HTMLEventObj
*event_obj
= NULL
;
2968 HRESULT hres
= S_OK
;
2970 eid
= attr_to_eid(event_name
);
2971 if(eid
== EVENTID_LAST
) {
2972 WARN("unknown event %s\n", debugstr_w(event_name
));
2973 return E_INVALIDARG
;
2976 if(event_var
&& V_VT(event_var
) != VT_EMPTY
&& V_VT(event_var
) != VT_ERROR
) {
2977 if(V_VT(event_var
) != VT_DISPATCH
) {
2978 FIXME("event_var %s not supported\n", debugstr_variant(event_var
));
2982 if(V_DISPATCH(event_var
)) {
2983 IHTMLEventObj
*event_iface
;
2985 hres
= IDispatch_QueryInterface(V_DISPATCH(event_var
), &IID_IHTMLEventObj
, (void**)&event_iface
);
2987 FIXME("No IHTMLEventObj iface\n");
2991 event_obj
= unsafe_impl_from_IHTMLEventObj(event_iface
);
2993 ERR("Not our IHTMLEventObj?\n");
2994 IHTMLEventObj_Release(event_iface
);
3001 event_obj
= alloc_event_obj(NULL
, dispex_compat_mode(&node
->event_target
.dispex
));
3003 return E_OUTOFMEMORY
;
3006 if(!event_obj
->event
)
3007 hres
= create_document_event(node
->doc
, eid
, &event_obj
->event
);
3009 if(SUCCEEDED(hres
)) {
3010 event_obj
->event
->event_obj
= &event_obj
->IHTMLEventObj_iface
;
3011 dispatch_event_object(&node
->event_target
, event_obj
->event
, DISPATCH_LEGACY
, NULL
);
3012 event_obj
->event
->event_obj
= NULL
;
3015 IHTMLEventObj_Release(&event_obj
->IHTMLEventObj_iface
);
3019 *cancelled
= VARIANT_TRUE
; /* FIXME */
3023 HRESULT
ensure_doc_nsevent_handler(HTMLDocumentNode
*doc
, nsIDOMNode
*nsnode
, eventid_t eid
)
3025 TRACE("%s\n", debugstr_w(event_info
[eid
].name
));
3031 case EVENTID_FOCUSIN
:
3032 doc
->event_vector
[eid
] = TRUE
;
3033 eid
= EVENTID_FOCUS
;
3035 case EVENTID_FOCUSOUT
:
3036 doc
->event_vector
[eid
] = TRUE
;
3045 if(event_info
[eid
].flags
& EVENT_DEFAULTLISTENER
) {
3047 }else if(event_info
[eid
].flags
& EVENT_BIND_TO_TARGET
) {
3049 nsnode
= doc
->node
.nsnode
;
3054 if(!nsnode
|| nsnode
== doc
->node
.nsnode
) {
3055 if(doc
->event_vector
[eid
])
3057 doc
->event_vector
[eid
] = TRUE
;
3060 add_nsevent_listener(doc
, nsnode
, event_info
[eid
].name
);
3064 void detach_events(HTMLDocumentNode
*doc
)
3066 if(doc
->event_vector
) {
3069 for(i
=0; i
< EVENTID_LAST
; i
++) {
3070 if(doc
->event_vector
[i
]) {
3071 detach_nsevent(doc
, event_info
[i
].name
);
3072 doc
->event_vector
[i
] = FALSE
;
3077 release_nsevents(doc
);
3080 static HRESULT
get_event_dispex_ref(EventTarget
*event_target
, eventid_t eid
, BOOL alloc
, VARIANT
**ret
)
3085 lstrcpyW(buf
+2, event_info
[eid
].name
);
3086 return dispex_get_dprop_ref(&event_target
->dispex
, buf
, alloc
, ret
);
3089 static event_listener_t
*get_onevent_listener(EventTarget
*event_target
, eventid_t eid
, BOOL alloc
)
3091 listener_container_t
*container
;
3092 event_listener_t
*listener
;
3094 container
= get_listener_container(event_target
, event_info
[eid
].name
, alloc
);
3098 LIST_FOR_EACH_ENTRY_REV(listener
, &container
->listeners
, event_listener_t
, entry
) {
3099 if(listener
->type
== LISTENER_TYPE_ONEVENT
)
3106 listener
= heap_alloc(sizeof(*listener
));
3110 listener
->type
= LISTENER_TYPE_ONEVENT
;
3111 listener
->function
= NULL
;
3112 list_add_tail(&container
->listeners
, &listener
->entry
);
3116 static void remove_event_handler(EventTarget
*event_target
, eventid_t eid
)
3118 event_listener_t
*listener
;
3122 hres
= get_event_dispex_ref(event_target
, eid
, FALSE
, &store
);
3124 VariantClear(store
);
3126 listener
= get_onevent_listener(event_target
, eid
, FALSE
);
3127 if(listener
&& listener
->function
) {
3128 IDispatch_Release(listener
->function
);
3129 listener
->function
= NULL
;
3133 static HRESULT
set_event_handler_disp(EventTarget
*event_target
, eventid_t eid
, IDispatch
*disp
)
3135 event_listener_t
*listener
;
3137 if(event_info
[eid
].flags
& EVENT_FIXME
)
3138 FIXME("unimplemented event %s\n", debugstr_w(event_info
[eid
].name
));
3140 remove_event_handler(event_target
, eid
);
3144 listener
= get_onevent_listener(event_target
, eid
, TRUE
);
3146 return E_OUTOFMEMORY
;
3148 if(listener
->function
)
3149 IDispatch_Release(listener
->function
);
3151 IDispatch_AddRef(listener
->function
= disp
);
3155 HRESULT
set_event_handler(EventTarget
*event_target
, eventid_t eid
, VARIANT
*var
)
3159 if(use_event_quirks(event_target
)) {
3160 WARN("attempt to set to VT_EMPTY in quirks mode\n");
3165 remove_event_handler(event_target
, eid
);
3169 return set_event_handler_disp(event_target
, eid
, V_DISPATCH(var
));
3175 if(!use_event_quirks(event_target
))
3176 FIXME("Setting to string %s not supported\n", debugstr_w(V_BSTR(var
)));
3179 * Setting event handler to string is a rare case and we don't want to
3180 * complicate nor increase memory of listener_container_t for that. Instead,
3181 * we store the value in DispatchEx, which can already handle custom
3184 remove_event_handler(event_target
, eid
);
3186 hres
= get_event_dispex_ref(event_target
, eid
, TRUE
, &v
);
3190 V_BSTR(v
) = SysAllocString(V_BSTR(var
));
3192 return E_OUTOFMEMORY
;
3198 FIXME("not handler %s\n", debugstr_variant(var
));
3205 HRESULT
get_event_handler(EventTarget
*event_target
, eventid_t eid
, VARIANT
*var
)
3207 event_listener_t
*listener
;
3211 hres
= get_event_dispex_ref(event_target
, eid
, FALSE
, &v
);
3212 if(SUCCEEDED(hres
) && V_VT(v
) != VT_EMPTY
) {
3213 V_VT(var
) = VT_EMPTY
;
3214 return VariantCopy(var
, v
);
3217 listener
= get_onevent_listener(event_target
, eid
, FALSE
);
3218 if(listener
&& listener
->function
) {
3219 V_VT(var
) = VT_DISPATCH
;
3220 V_DISPATCH(var
) = listener
->function
;
3221 IDispatch_AddRef(V_DISPATCH(var
));
3223 V_VT(var
) = VT_NULL
;
3229 HRESULT
attach_event(EventTarget
*event_target
, BSTR name
, IDispatch
*disp
, VARIANT_BOOL
*res
)
3231 listener_container_t
*container
;
3232 event_listener_t
*listener
;
3235 eid
= attr_to_eid(name
);
3236 if(eid
== EVENTID_LAST
) {
3237 WARN("Unknown event\n");
3238 *res
= VARIANT_TRUE
;
3242 container
= get_listener_container(event_target
, event_info
[eid
].name
, TRUE
);
3244 return E_OUTOFMEMORY
;
3246 listener
= heap_alloc(sizeof(*listener
));
3248 return E_OUTOFMEMORY
;
3250 listener
->type
= LISTENER_TYPE_ATTACHED
;
3251 IDispatch_AddRef(listener
->function
= disp
);
3252 if(use_event_quirks(event_target
))
3253 list_add_head(&container
->listeners
, &listener
->entry
);
3255 list_add_tail(&container
->listeners
, &listener
->entry
);
3257 *res
= VARIANT_TRUE
;
3261 HRESULT
detach_event(EventTarget
*event_target
, BSTR name
, IDispatch
*disp
)
3265 eid
= attr_to_eid(name
);
3266 if(eid
== EVENTID_LAST
) {
3267 WARN("Unknown event\n");
3271 remove_event_listener(event_target
, event_info
[eid
].name
, LISTENER_TYPE_ATTACHED
, disp
);
3275 void bind_target_event(HTMLDocumentNode
*doc
, EventTarget
*event_target
, const WCHAR
*event
, IDispatch
*disp
)
3279 TRACE("(%p %p %s %p)\n", doc
, event_target
, debugstr_w(event
), disp
);
3281 eid
= attr_to_eid(event
);
3282 if(eid
== EVENTID_LAST
) {
3283 WARN("Unsupported event %s\n", debugstr_w(event
));
3287 set_event_handler_disp(event_target
, eid
, disp
);
3290 void update_doc_cp_events(HTMLDocumentNode
*doc
, cp_static_data_t
*cp
)
3294 for(i
=0; i
< EVENTID_LAST
; i
++) {
3295 if((event_info
[i
].flags
& EVENT_DEFAULTLISTENER
) && is_cp_event(cp
, event_info
[i
].dispid
))
3296 ensure_doc_nsevent_handler(doc
, NULL
, i
);
3300 void check_event_attr(HTMLDocumentNode
*doc
, nsIDOMElement
*nselem
)
3302 nsIDOMMozNamedAttrMap
*attr_map
;
3303 const PRUnichar
*name
, *value
;
3304 nsAString name_str
, value_str
;
3305 HTMLDOMNode
*node
= NULL
;
3314 nsres
= nsIDOMElement_HasAttributes(nselem
, &has_attrs
);
3315 if(NS_FAILED(nsres
) || !has_attrs
)
3318 nsres
= nsIDOMElement_GetAttributes(nselem
, &attr_map
);
3319 if(NS_FAILED(nsres
))
3322 nsres
= nsIDOMMozNamedAttrMap_GetLength(attr_map
, &length
);
3323 assert(nsres
== NS_OK
);
3325 nsAString_Init(&name_str
, NULL
);
3326 nsAString_Init(&value_str
, NULL
);
3328 for(i
= 0; i
< length
; i
++) {
3329 nsres
= nsIDOMMozNamedAttrMap_Item(attr_map
, i
, &attr
);
3330 if(NS_FAILED(nsres
))
3333 nsres
= nsIDOMAttr_GetName(attr
, &name_str
);
3334 if(NS_FAILED(nsres
)) {
3335 nsIDOMAttr_Release(attr
);
3339 nsAString_GetData(&name_str
, &name
);
3340 eid
= attr_to_eid(name
);
3341 if(eid
== EVENTID_LAST
) {
3342 nsIDOMAttr_Release(attr
);
3346 nsres
= nsIDOMAttr_GetValue(attr
, &value_str
);
3347 nsIDOMAttr_Release(attr
);
3348 if(NS_FAILED(nsres
))
3351 nsAString_GetData(&value_str
, &value
);
3355 TRACE("%p.%s = %s\n", nselem
, debugstr_w(name
), debugstr_w(value
));
3357 disp
= script_parse_event(doc
->window
, value
);
3362 hres
= get_node((nsIDOMNode
*)nselem
, TRUE
, &node
);
3364 IDispatch_Release(disp
);
3369 set_event_handler_disp(get_node_event_prop_target(node
, eid
), eid
, disp
);
3370 IDispatch_Release(disp
);
3375 nsAString_Finish(&name_str
);
3376 nsAString_Finish(&value_str
);
3377 nsIDOMMozNamedAttrMap_Release(attr_map
);
3380 HRESULT
doc_init_events(HTMLDocumentNode
*doc
)
3385 doc
->event_vector
= heap_alloc_zero(EVENTID_LAST
*sizeof(BOOL
));
3386 if(!doc
->event_vector
)
3387 return E_OUTOFMEMORY
;
3391 for(i
=0; i
< EVENTID_LAST
; i
++) {
3392 if(event_info
[i
].flags
& EVENT_HASDEFAULTHANDLERS
) {
3393 hres
= ensure_doc_nsevent_handler(doc
, NULL
, i
);
3402 static inline EventTarget
*impl_from_IEventTarget(IEventTarget
*iface
)
3404 return CONTAINING_RECORD(iface
, EventTarget
, IEventTarget_iface
);
3407 static HRESULT WINAPI
EventTarget_QueryInterface(IEventTarget
*iface
, REFIID riid
, void **ppv
)
3409 EventTarget
*This
= impl_from_IEventTarget(iface
);
3410 return IDispatchEx_QueryInterface(&This
->dispex
.IDispatchEx_iface
, riid
, ppv
);
3413 static ULONG WINAPI
EventTarget_AddRef(IEventTarget
*iface
)
3415 EventTarget
*This
= impl_from_IEventTarget(iface
);
3416 return IDispatchEx_AddRef(&This
->dispex
.IDispatchEx_iface
);
3419 static ULONG WINAPI
EventTarget_Release(IEventTarget
*iface
)
3421 EventTarget
*This
= impl_from_IEventTarget(iface
);
3422 return IDispatchEx_Release(&This
->dispex
.IDispatchEx_iface
);
3425 static HRESULT WINAPI
EventTarget_GetTypeInfoCount(IEventTarget
*iface
, UINT
*pctinfo
)
3427 EventTarget
*This
= impl_from_IEventTarget(iface
);
3428 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
3431 static HRESULT WINAPI
EventTarget_GetTypeInfo(IEventTarget
*iface
, UINT iTInfo
,
3432 LCID lcid
, ITypeInfo
**ppTInfo
)
3434 EventTarget
*This
= impl_from_IEventTarget(iface
);
3435 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
3438 static HRESULT WINAPI
EventTarget_GetIDsOfNames(IEventTarget
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
3439 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
3441 EventTarget
*This
= impl_from_IEventTarget(iface
);
3442 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
,
3443 rgszNames
, cNames
, lcid
, rgDispId
);
3446 static HRESULT WINAPI
EventTarget_Invoke(IEventTarget
*iface
, DISPID dispIdMember
,
3447 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
3448 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
3450 EventTarget
*This
= impl_from_IEventTarget(iface
);
3451 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
,
3452 riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
3455 static HRESULT WINAPI
EventTarget_addEventListener(IEventTarget
*iface
, BSTR type
,
3456 IDispatch
*function
, VARIANT_BOOL capture
)
3458 EventTarget
*This
= impl_from_IEventTarget(iface
);
3459 listener_type_t listener_type
= capture
? LISTENER_TYPE_CAPTURE
: LISTENER_TYPE_BUBBLE
;
3460 listener_container_t
*container
;
3461 event_listener_t
*listener
;
3463 TRACE("(%p)->(%s %p %x)\n", This
, debugstr_w(type
), function
, capture
);
3465 container
= get_listener_container(This
, type
, TRUE
);
3467 return E_OUTOFMEMORY
;
3469 /* check for duplicates */
3470 LIST_FOR_EACH_ENTRY(listener
, &container
->listeners
, event_listener_t
, entry
) {
3471 if(listener
->type
== listener_type
&& listener
->function
== function
)
3475 listener
= heap_alloc(sizeof(*listener
));
3477 return E_OUTOFMEMORY
;
3479 listener
->type
= listener_type
;
3480 IDispatch_AddRef(listener
->function
= function
);
3481 list_add_tail(&container
->listeners
, &listener
->entry
);
3485 static HRESULT WINAPI
EventTarget_removeEventListener(IEventTarget
*iface
, BSTR type
,
3486 IDispatch
*listener
, VARIANT_BOOL capture
)
3488 EventTarget
*This
= impl_from_IEventTarget(iface
);
3490 TRACE("(%p)->(%s %p %x)\n", This
, debugstr_w(type
), listener
, capture
);
3492 remove_event_listener(This
, type
, capture
? LISTENER_TYPE_CAPTURE
: LISTENER_TYPE_BUBBLE
, listener
);
3496 static HRESULT WINAPI
EventTarget_dispatchEvent(IEventTarget
*iface
, IDOMEvent
*event_iface
, VARIANT_BOOL
*result
)
3498 EventTarget
*This
= impl_from_IEventTarget(iface
);
3499 DOMEvent
*event
= unsafe_impl_from_IDOMEvent(event_iface
);
3501 TRACE("(%p)->(%p %p)\n", This
, event
, result
);
3504 WARN("Invalid event\n");
3505 return E_INVALIDARG
;
3508 return dispatch_event_object(This
, event
, DISPATCH_STANDARD
, result
);
3511 static HRESULT
IEventTarget_addEventListener_hook(DispatchEx
*dispex
, WORD flags
,
3512 DISPPARAMS
*dp
, VARIANT
*res
, EXCEPINFO
*ei
, IServiceProvider
*caller
)
3514 /* If only two arguments were given, implicitly set capture to false */
3515 if((flags
& DISPATCH_METHOD
) && dp
->cArgs
== 2 && !dp
->cNamedArgs
) {
3517 DISPPARAMS new_dp
= {args
, NULL
, 3, 0};
3518 V_VT(args
) = VT_BOOL
;
3519 V_BOOL(args
) = VARIANT_FALSE
;
3520 args
[1] = dp
->rgvarg
[0];
3521 args
[2] = dp
->rgvarg
[1];
3523 TRACE("implicit capture\n");
3525 return dispex_call_builtin(dispex
, DISPID_IEVENTTARGET_ADDEVENTLISTENER
, &new_dp
, res
, ei
, caller
);
3528 return S_FALSE
; /* fallback to default */
3531 static HRESULT
IEventTarget_removeEventListener_hook(DispatchEx
*dispex
, WORD flags
,
3532 DISPPARAMS
*dp
, VARIANT
*res
, EXCEPINFO
*ei
, IServiceProvider
*caller
)
3534 /* If only two arguments were given, implicitly set capture to false */
3535 if((flags
& DISPATCH_METHOD
) && dp
->cArgs
== 2 && !dp
->cNamedArgs
) {
3537 DISPPARAMS new_dp
= {args
, NULL
, 3, 0};
3538 V_VT(args
) = VT_BOOL
;
3539 V_BOOL(args
) = VARIANT_FALSE
;
3540 args
[1] = dp
->rgvarg
[0];
3541 args
[2] = dp
->rgvarg
[1];
3543 TRACE("implicit capture\n");
3545 return dispex_call_builtin(dispex
, DISPID_IEVENTTARGET_REMOVEEVENTLISTENER
, &new_dp
, res
, ei
, caller
);
3548 return S_FALSE
; /* fallback to default */
3551 static const IEventTargetVtbl EventTargetVtbl
= {
3552 EventTarget_QueryInterface
,
3554 EventTarget_Release
,
3555 EventTarget_GetTypeInfoCount
,
3556 EventTarget_GetTypeInfo
,
3557 EventTarget_GetIDsOfNames
,
3559 EventTarget_addEventListener
,
3560 EventTarget_removeEventListener
,
3561 EventTarget_dispatchEvent
3564 static EventTarget
*unsafe_impl_from_IEventTarget(IEventTarget
*iface
)
3566 return iface
&& iface
->lpVtbl
== &EventTargetVtbl
? impl_from_IEventTarget(iface
) : NULL
;
3569 static HRESULT
get_gecko_target(IEventTarget
*target
, nsIDOMEventTarget
**ret
)
3571 EventTarget
*event_target
= unsafe_impl_from_IEventTarget(target
);
3572 const event_target_vtbl_t
*vtbl
;
3576 WARN("Not our IEventTarget implementation\n");
3577 return E_INVALIDARG
;
3580 vtbl
= (const event_target_vtbl_t
*)dispex_get_vtbl(&event_target
->dispex
);
3581 nsres
= nsISupports_QueryInterface(vtbl
->get_gecko_target(&event_target
->dispex
),
3582 &IID_nsIDOMEventTarget
, (void**)ret
);
3583 assert(nsres
== NS_OK
);
3587 HRESULT
EventTarget_QI(EventTarget
*event_target
, REFIID riid
, void **ppv
)
3589 if(IsEqualGUID(riid
, &IID_IEventTarget
)) {
3590 if(use_event_quirks(event_target
)) {
3591 WARN("IEventTarget queried, but not supported by in document mode\n");
3593 return E_NOINTERFACE
;
3595 IEventTarget_AddRef(&event_target
->IEventTarget_iface
);
3596 *ppv
= &event_target
->IEventTarget_iface
;
3600 if(dispex_query_interface(&event_target
->dispex
, riid
, ppv
))
3601 return *ppv
? S_OK
: E_NOINTERFACE
;
3603 WARN("(%p)->(%s %p)\n", event_target
, debugstr_mshtml_guid(riid
), ppv
);
3605 return E_NOINTERFACE
;
3608 void EventTarget_init_dispex_info(dispex_data_t
*dispex_info
, compat_mode_t compat_mode
)
3610 static const dispex_hook_t IEventTarget_hooks
[] = {
3611 {DISPID_IEVENTTARGET_ADDEVENTLISTENER
, IEventTarget_addEventListener_hook
},
3612 {DISPID_IEVENTTARGET_REMOVEEVENTLISTENER
, IEventTarget_removeEventListener_hook
},
3616 if(compat_mode
>= COMPAT_MODE_IE9
)
3617 dispex_info_add_interface(dispex_info
, IEventTarget_tid
, IEventTarget_hooks
);
3620 static int event_id_cmp(const void *key
, const struct wine_rb_entry
*entry
)
3622 return wcscmp(key
, WINE_RB_ENTRY_VALUE(entry
, listener_container_t
, entry
)->type
);
3625 void EventTarget_Init(EventTarget
*event_target
, IUnknown
*outer
, dispex_static_data_t
*dispex_data
,
3626 compat_mode_t compat_mode
)
3628 init_dispatch(&event_target
->dispex
, outer
, dispex_data
, compat_mode
);
3629 event_target
->IEventTarget_iface
.lpVtbl
= &EventTargetVtbl
;
3630 wine_rb_init(&event_target
->handler_map
, event_id_cmp
);
3633 void release_event_target(EventTarget
*event_target
)
3635 listener_container_t
*iter
, *iter2
;
3637 WINE_RB_FOR_EACH_ENTRY_DESTRUCTOR(iter
, iter2
, &event_target
->handler_map
, listener_container_t
, entry
) {
3638 while(!list_empty(&iter
->listeners
)) {
3639 event_listener_t
*listener
= LIST_ENTRY(list_head(&iter
->listeners
), event_listener_t
, entry
);
3640 if(listener
->function
)
3641 IDispatch_Release(listener
->function
);
3642 list_remove(&listener
->entry
);
3643 heap_free(listener
);