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
;
74 static const WCHAR
*event_types
[] = {
93 /* Use Gecko default listener (it's registered on window object for DOM nodes). */
94 #define EVENT_DEFAULTLISTENER 0x0001
95 /* Register Gecko listener on target itself (unlike EVENT_DEFAULTLISTENER). */
96 #define EVENT_BIND_TO_TARGET 0x0002
97 /* Event bubbles by default (unless explicitly specified otherwise). */
98 #define EVENT_BUBBLES 0x0004
99 /* Event is cancelable by default (unless explicitly specified otherwise). */
100 #define EVENT_CANCELABLE 0x0008
101 /* Event may have default handler (so we always have to register Gecko listener). */
102 #define EVENT_HASDEFAULTHANDLERS 0x0020
103 /* Ecent is not supported properly, print FIXME message when it's used. */
104 #define EVENT_FIXME 0x0040
106 /* mouse event flags for fromElement and toElement implementation */
107 #define EVENT_MOUSE_TO_RELATED 0x0100
108 #define EVENT_MOUSE_FROM_RELATED 0x0200
110 /* Keep these sorted case sensitively */
111 static const event_info_t event_info
[] = {
112 {L
"DOMContentLoaded", EVENT_TYPE_EVENT
, 0,
113 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
114 {L
"abort", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONABORT
,
115 EVENT_BIND_TO_TARGET
},
116 {L
"animationend", EVENT_TYPE_EVENT
, DISPID_EVPROP_ONANIMATIONEND
,
117 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
},
118 {L
"animationstart", EVENT_TYPE_EVENT
, DISPID_EVPROP_ONANIMATIONSTART
,
119 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
},
120 {L
"beforeactivate", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONBEFOREACTIVATE
,
121 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
122 {L
"beforeunload", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONBEFOREUNLOAD
,
123 EVENT_DEFAULTLISTENER
| EVENT_CANCELABLE
},
124 {L
"blur", EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONBLUR
,
125 EVENT_DEFAULTLISTENER
},
126 {L
"change", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONCHANGE
,
127 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
},
128 {L
"click", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONCLICK
,
129 EVENT_DEFAULTLISTENER
| EVENT_HASDEFAULTHANDLERS
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
130 {L
"contextmenu", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONCONTEXTMENU
,
131 EVENT_BUBBLES
| EVENT_CANCELABLE
},
132 {L
"dataavailable", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONDATAAVAILABLE
,
133 EVENT_FIXME
| EVENT_BUBBLES
},
134 {L
"dblclick", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONDBLCLICK
,
135 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
136 {L
"drag", EVENT_TYPE_DRAG
, DISPID_EVMETH_ONDRAG
,
137 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
138 {L
"dragstart", EVENT_TYPE_DRAG
, DISPID_EVMETH_ONDRAGSTART
,
139 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
140 {L
"error", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONERROR
,
141 EVENT_BIND_TO_TARGET
},
142 {L
"focus", EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONFOCUS
,
143 EVENT_DEFAULTLISTENER
},
144 {L
"focusin", EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONFOCUSIN
,
146 {L
"focusout", EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONFOCUSOUT
,
148 {L
"help", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONHELP
,
149 EVENT_BUBBLES
| EVENT_CANCELABLE
},
150 {L
"input", EVENT_TYPE_EVENT
, DISPID_UNKNOWN
,
151 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
},
152 {L
"keydown", EVENT_TYPE_KEYBOARD
, DISPID_EVMETH_ONKEYDOWN
,
153 EVENT_DEFAULTLISTENER
| EVENT_HASDEFAULTHANDLERS
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
154 {L
"keypress", EVENT_TYPE_KEYBOARD
, DISPID_EVMETH_ONKEYPRESS
,
155 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
156 {L
"keyup", EVENT_TYPE_KEYBOARD
, DISPID_EVMETH_ONKEYUP
,
157 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
158 {L
"load", EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONLOAD
,
159 EVENT_BIND_TO_TARGET
},
160 {L
"message", EVENT_TYPE_MESSAGE
, DISPID_EVMETH_ONMESSAGE
,
162 {L
"mousedown", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEDOWN
,
163 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
164 {L
"mousemove", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEMOVE
,
165 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
| EVENT_MOUSE_FROM_RELATED
},
166 {L
"mouseout", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEOUT
,
167 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
| EVENT_MOUSE_TO_RELATED
},
168 {L
"mouseover", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEOVER
,
169 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
| EVENT_MOUSE_FROM_RELATED
},
170 {L
"mouseup", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEUP
,
171 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
172 {L
"mousewheel", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEWHEEL
,
174 {L
"msthumbnailclick", EVENT_TYPE_MOUSE
, DISPID_EVPROP_ONMSTHUMBNAILCLICK
,
176 {L
"paste", EVENT_TYPE_CLIPBOARD
, DISPID_EVMETH_ONPASTE
,
177 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
178 {L
"progress", EVENT_TYPE_PROGRESS
, DISPID_EVPROP_PROGRESS
,
179 EVENT_BIND_TO_TARGET
},
180 {L
"readystatechange", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONREADYSTATECHANGE
,
182 {L
"resize", EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONRESIZE
,
183 EVENT_DEFAULTLISTENER
},
184 {L
"scroll", EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONSCROLL
,
185 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
/* FIXME: not for elements */},
186 {L
"selectionchange", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONSELECTIONCHANGE
,
188 {L
"selectstart", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONSELECTSTART
,
189 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
190 {L
"submit", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONSUBMIT
,
191 EVENT_DEFAULTLISTENER
| EVENT_HASDEFAULTHANDLERS
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
192 {L
"timeout", EVENT_TYPE_PROGRESS
, DISPID_EVPROP_TIMEOUT
,
193 EVENT_BIND_TO_TARGET
},
194 {L
"unload", EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONUNLOAD
,
198 C_ASSERT(ARRAY_SIZE(event_info
) == EVENTID_LAST
);
200 static eventid_t
str_to_eid(const WCHAR
*str
)
202 unsigned i
, a
= 0, b
= ARRAY_SIZE(event_info
);
207 if(!(c
= wcscmp(event_info
[i
].name
, str
)))
216 static eventid_t
attr_to_eid(const WCHAR
*str
)
218 unsigned i
, a
= 0, b
= ARRAY_SIZE(event_info
);
221 if((str
[0] != 'o' && str
[0] != 'O') || (str
[1] != 'n' && str
[1] != 'N'))
226 if(!(c
= wcscmp(event_info
[i
].name
, str
+2)))
227 return event_info
[i
].dispid
? i
: EVENTID_LAST
;
235 const WCHAR
*get_event_name(eventid_t eid
)
237 return event_info
[eid
].name
;
240 static listener_container_t
*get_listener_container(EventTarget
*event_target
, const WCHAR
*type
, BOOL alloc
)
242 const event_target_vtbl_t
*vtbl
;
243 listener_container_t
*container
;
244 struct wine_rb_entry
*entry
;
248 entry
= wine_rb_get(&event_target
->handler_map
, type
);
250 return WINE_RB_ENTRY_VALUE(entry
, listener_container_t
, entry
);
254 eid
= str_to_eid(type
);
255 if(eid
!= EVENTID_LAST
&& (event_info
[eid
].flags
& EVENT_FIXME
))
256 FIXME("unimplemented event %s\n", debugstr_w(event_info
[eid
].name
));
258 type_len
= lstrlenW(type
);
259 container
= heap_alloc(FIELD_OFFSET(listener_container_t
, type
[type_len
+1]));
262 memcpy(container
->type
, type
, (type_len
+ 1) * sizeof(WCHAR
));
263 list_init(&container
->listeners
);
264 vtbl
= dispex_get_vtbl(&event_target
->dispex
);
265 if (!vtbl
->bind_event
)
266 FIXME("Unsupported event binding on target %p\n", event_target
);
267 else if(eid
!= EVENTID_LAST
)
268 vtbl
->bind_event(&event_target
->dispex
, eid
);
270 wine_rb_put(&event_target
->handler_map
, container
->type
, &container
->entry
);
274 static void remove_event_listener(EventTarget
*event_target
, const WCHAR
*type_name
, listener_type_t type
, IDispatch
*function
)
276 listener_container_t
*container
;
277 event_listener_t
*listener
;
279 container
= get_listener_container(event_target
, type_name
, FALSE
);
283 LIST_FOR_EACH_ENTRY(listener
, &container
->listeners
, event_listener_t
, entry
) {
284 if(listener
->function
== function
&& listener
->type
== type
) {
285 IDispatch_Release(listener
->function
);
286 list_remove(&listener
->entry
);
293 static HRESULT
get_gecko_target(IEventTarget
*,nsIDOMEventTarget
**);
297 IHTMLEventObj IHTMLEventObj_iface
;
302 VARIANT return_value
;
305 static inline HTMLEventObj
*impl_from_IHTMLEventObj(IHTMLEventObj
*iface
)
307 return CONTAINING_RECORD(iface
, HTMLEventObj
, IHTMLEventObj_iface
);
310 static HRESULT WINAPI
HTMLEventObj_QueryInterface(IHTMLEventObj
*iface
, REFIID riid
, void **ppv
)
312 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
314 TRACE("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
316 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
317 *ppv
= &This
->IHTMLEventObj_iface
;
318 }else if(IsEqualGUID(&IID_IHTMLEventObj
, riid
)) {
319 *ppv
= &This
->IHTMLEventObj_iface
;
320 }else if(dispex_query_interface(&This
->dispex
, riid
, ppv
)) {
321 return *ppv
? S_OK
: E_NOINTERFACE
;
324 WARN("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
325 return E_NOINTERFACE
;
328 IUnknown_AddRef((IUnknown
*)*ppv
);
332 static ULONG WINAPI
HTMLEventObj_AddRef(IHTMLEventObj
*iface
)
334 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
335 LONG ref
= InterlockedIncrement(&This
->ref
);
337 TRACE("(%p) ref=%ld\n", This
, ref
);
342 static ULONG WINAPI
HTMLEventObj_Release(IHTMLEventObj
*iface
)
344 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
345 LONG ref
= InterlockedDecrement(&This
->ref
);
347 TRACE("(%p) ref=%ld\n", This
, ref
);
351 IDOMEvent_Release(&This
->event
->IDOMEvent_iface
);
352 release_dispex(&This
->dispex
);
359 static HRESULT WINAPI
HTMLEventObj_GetTypeInfoCount(IHTMLEventObj
*iface
, UINT
*pctinfo
)
361 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
362 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
365 static HRESULT WINAPI
HTMLEventObj_GetTypeInfo(IHTMLEventObj
*iface
, UINT iTInfo
,
366 LCID lcid
, ITypeInfo
**ppTInfo
)
368 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
369 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
372 static HRESULT WINAPI
HTMLEventObj_GetIDsOfNames(IHTMLEventObj
*iface
, REFIID riid
,
373 LPOLESTR
*rgszNames
, UINT cNames
,
374 LCID lcid
, DISPID
*rgDispId
)
376 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
377 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
381 static HRESULT WINAPI
HTMLEventObj_Invoke(IHTMLEventObj
*iface
, DISPID dispIdMember
,
382 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
383 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
385 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
386 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
387 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
390 static HRESULT WINAPI
HTMLEventObj_get_srcElement(IHTMLEventObj
*iface
, IHTMLElement
**p
)
392 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
394 TRACE("(%p)->(%p)\n", This
, p
);
401 return IDOMEvent_get_srcElement(&This
->event
->IDOMEvent_iface
, p
);
404 static HRESULT WINAPI
HTMLEventObj_get_altKey(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
406 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
407 cpp_bool ret
= FALSE
;
409 TRACE("(%p)->(%p)\n", This
, p
);
411 if(This
->event
&& This
->event
->mouse_event
)
412 return IDOMMouseEvent_get_altKey(&This
->event
->IDOMMouseEvent_iface
, p
);
414 if(This
->event
&& This
->event
->keyboard_event
)
415 return IDOMKeyboardEvent_get_altKey(&This
->event
->IDOMKeyboardEvent_iface
, p
);
417 *p
= variant_bool(ret
);
421 static HRESULT WINAPI
HTMLEventObj_get_ctrlKey(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
423 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
424 cpp_bool ret
= FALSE
;
426 TRACE("(%p)->(%p)\n", This
, p
);
428 if(This
->event
&& This
->event
->mouse_event
)
429 return IDOMMouseEvent_get_ctrlKey(&This
->event
->IDOMMouseEvent_iface
, p
);
431 if(This
->event
&& This
->event
->keyboard_event
)
432 return IDOMKeyboardEvent_get_ctrlKey(&This
->event
->IDOMKeyboardEvent_iface
, p
);
434 *p
= variant_bool(ret
);
438 static HRESULT WINAPI
HTMLEventObj_get_shiftKey(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
440 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
441 cpp_bool ret
= FALSE
;
443 TRACE("(%p)->(%p)\n", This
, p
);
445 if(This
->event
&& This
->event
->mouse_event
)
446 return IDOMMouseEvent_get_shiftKey(&This
->event
->IDOMMouseEvent_iface
, p
);
448 if(This
->event
&& This
->event
->keyboard_event
)
449 return IDOMKeyboardEvent_get_shiftKey(&This
->event
->IDOMKeyboardEvent_iface
, p
);
451 *p
= variant_bool(ret
);
455 static HRESULT WINAPI
HTMLEventObj_put_returnValue(IHTMLEventObj
*iface
, VARIANT v
)
457 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
459 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&v
));
461 if(V_VT(&v
) != VT_BOOL
) {
462 FIXME("unsupported value %s\n", debugstr_variant(&v
));
463 return DISP_E_BADVARTYPE
;
466 This
->return_value
= v
;
467 if(!V_BOOL(&v
) && This
->event
)
468 IDOMEvent_preventDefault(&This
->event
->IDOMEvent_iface
);
472 static HRESULT WINAPI
HTMLEventObj_get_returnValue(IHTMLEventObj
*iface
, VARIANT
*p
)
474 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
476 TRACE("(%p)->(%p)\n", This
, p
);
479 return VariantCopy(p
, &This
->return_value
);
482 static HRESULT WINAPI
HTMLEventObj_put_cancelBubble(IHTMLEventObj
*iface
, VARIANT_BOOL v
)
484 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
486 TRACE("(%p)->(%x)\n", This
, v
);
489 IDOMEvent_stopPropagation(&This
->event
->IDOMEvent_iface
);
493 static HRESULT WINAPI
HTMLEventObj_get_cancelBubble(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
495 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
497 TRACE("(%p)->(%p)\n", This
, p
);
499 *p
= variant_bool(This
->event
&& This
->event
->stop_propagation
);
503 static HRESULT WINAPI
HTMLEventObj_get_fromElement(IHTMLEventObj
*iface
, IHTMLElement
**p
)
505 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
507 TRACE("(%p)->(%p)\n", This
, p
);
509 if(This
->event
&& This
->event
->mouse_event
)
510 return IDOMMouseEvent_get_fromElement(&This
->event
->IDOMMouseEvent_iface
, p
);
516 static HRESULT WINAPI
HTMLEventObj_get_toElement(IHTMLEventObj
*iface
, IHTMLElement
**p
)
518 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
520 TRACE("(%p)->(%p)\n", This
, p
);
522 if(This
->event
&& This
->event
->mouse_event
)
523 return IDOMMouseEvent_get_toElement(&This
->event
->IDOMMouseEvent_iface
, p
);
529 static HRESULT WINAPI
HTMLEventObj_put_keyCode(IHTMLEventObj
*iface
, LONG v
)
531 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
532 FIXME("(%p)->(%ld)\n", This
, v
);
536 static HRESULT WINAPI
HTMLEventObj_get_keyCode(IHTMLEventObj
*iface
, LONG
*p
)
538 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
540 TRACE("(%p)->(%p)\n", This
, p
);
542 if(This
->event
&& This
->event
->keyboard_event
)
543 return IDOMKeyboardEvent_get_keyCode(&This
->event
->IDOMKeyboardEvent_iface
, p
);
549 static HRESULT WINAPI
HTMLEventObj_get_button(IHTMLEventObj
*iface
, LONG
*p
)
551 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
554 TRACE("(%p)->(%p)\n", This
, p
);
556 if(This
->event
&& This
->event
->mouse_event
) {
558 hres
= IDOMMouseEvent_get_button(&This
->event
->IDOMMouseEvent_iface
, &button
);
567 static HRESULT WINAPI
HTMLEventObj_get_type(IHTMLEventObj
*iface
, BSTR
*p
)
569 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
571 TRACE("(%p)->(%p)\n", This
, p
);
578 return IDOMEvent_get_type(&This
->event
->IDOMEvent_iface
, p
);
581 static HRESULT WINAPI
HTMLEventObj_get_qualifier(IHTMLEventObj
*iface
, BSTR
*p
)
583 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
585 FIXME("(%p)->(%p)\n", This
, p
);
591 static HRESULT WINAPI
HTMLEventObj_get_reason(IHTMLEventObj
*iface
, LONG
*p
)
593 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
595 FIXME("(%p)->(%p)\n", This
, p
);
601 static HRESULT WINAPI
HTMLEventObj_get_x(IHTMLEventObj
*iface
, LONG
*p
)
603 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
606 TRACE("(%p)->(%p)\n", This
, p
);
608 if(This
->event
&& This
->event
->ui_event
) {
611 /* NOTE: pageX is not exactly right here. */
612 nsres
= nsIDOMUIEvent_GetPageX(This
->event
->ui_event
, &x
);
613 assert(nsres
== NS_OK
);
620 static HRESULT WINAPI
HTMLEventObj_get_y(IHTMLEventObj
*iface
, LONG
*p
)
622 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
625 TRACE("(%p)->(%p)\n", This
, p
);
627 if(This
->event
&& This
->event
->ui_event
) {
630 /* NOTE: pageY is not exactly right here. */
631 nsres
= nsIDOMUIEvent_GetPageY(This
->event
->ui_event
, &y
);
632 assert(nsres
== NS_OK
);
639 static HRESULT WINAPI
HTMLEventObj_get_clientX(IHTMLEventObj
*iface
, LONG
*p
)
641 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
643 TRACE("(%p)->(%p)\n", This
, p
);
645 if(This
->event
&& This
->event
->mouse_event
)
646 return IDOMMouseEvent_get_clientX(&This
->event
->IDOMMouseEvent_iface
, p
);
652 static HRESULT WINAPI
HTMLEventObj_get_clientY(IHTMLEventObj
*iface
, LONG
*p
)
654 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
656 TRACE("(%p)->(%p)\n", This
, p
);
658 if(This
->event
&& This
->event
->mouse_event
)
659 return IDOMMouseEvent_get_clientY(&This
->event
->IDOMMouseEvent_iface
, p
);
665 static HRESULT WINAPI
HTMLEventObj_get_offsetX(IHTMLEventObj
*iface
, LONG
*p
)
667 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
669 TRACE("(%p)->(%p)\n", This
, p
);
671 if(This
->event
&& This
->event
->mouse_event
)
672 return IDOMMouseEvent_get_offsetX(&This
->event
->IDOMMouseEvent_iface
, p
);
678 static HRESULT WINAPI
HTMLEventObj_get_offsetY(IHTMLEventObj
*iface
, LONG
*p
)
680 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
682 TRACE("(%p)->(%p)\n", This
, p
);
684 if(This
->event
&& This
->event
->mouse_event
)
685 return IDOMMouseEvent_get_offsetY(&This
->event
->IDOMMouseEvent_iface
, p
);
691 static HRESULT WINAPI
HTMLEventObj_get_screenX(IHTMLEventObj
*iface
, LONG
*p
)
693 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
695 TRACE("(%p)->(%p)\n", This
, p
);
697 if(This
->event
&& This
->event
->mouse_event
)
698 return IDOMMouseEvent_get_screenX(&This
->event
->IDOMMouseEvent_iface
, p
);
704 static HRESULT WINAPI
HTMLEventObj_get_screenY(IHTMLEventObj
*iface
, LONG
*p
)
706 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
708 TRACE("(%p)->(%p)\n", This
, p
);
710 if(This
->event
&& This
->event
->mouse_event
)
711 return IDOMMouseEvent_get_screenY(&This
->event
->IDOMMouseEvent_iface
, p
);
717 static HRESULT WINAPI
HTMLEventObj_get_srcFilter(IHTMLEventObj
*iface
, IDispatch
**p
)
719 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
721 FIXME("(%p)->(%p)\n", This
, p
);
727 static const IHTMLEventObjVtbl HTMLEventObjVtbl
= {
728 HTMLEventObj_QueryInterface
,
730 HTMLEventObj_Release
,
731 HTMLEventObj_GetTypeInfoCount
,
732 HTMLEventObj_GetTypeInfo
,
733 HTMLEventObj_GetIDsOfNames
,
735 HTMLEventObj_get_srcElement
,
736 HTMLEventObj_get_altKey
,
737 HTMLEventObj_get_ctrlKey
,
738 HTMLEventObj_get_shiftKey
,
739 HTMLEventObj_put_returnValue
,
740 HTMLEventObj_get_returnValue
,
741 HTMLEventObj_put_cancelBubble
,
742 HTMLEventObj_get_cancelBubble
,
743 HTMLEventObj_get_fromElement
,
744 HTMLEventObj_get_toElement
,
745 HTMLEventObj_put_keyCode
,
746 HTMLEventObj_get_keyCode
,
747 HTMLEventObj_get_button
,
748 HTMLEventObj_get_type
,
749 HTMLEventObj_get_qualifier
,
750 HTMLEventObj_get_reason
,
753 HTMLEventObj_get_clientX
,
754 HTMLEventObj_get_clientY
,
755 HTMLEventObj_get_offsetX
,
756 HTMLEventObj_get_offsetY
,
757 HTMLEventObj_get_screenX
,
758 HTMLEventObj_get_screenY
,
759 HTMLEventObj_get_srcFilter
762 static inline HTMLEventObj
*unsafe_impl_from_IHTMLEventObj(IHTMLEventObj
*iface
)
764 return iface
->lpVtbl
== &HTMLEventObjVtbl
? impl_from_IHTMLEventObj(iface
) : NULL
;
767 static const tid_t HTMLEventObj_iface_tids
[] = {
772 static dispex_static_data_t HTMLEventObj_dispex
= {
776 HTMLEventObj_iface_tids
779 static HTMLEventObj
*alloc_event_obj(DOMEvent
*event
, compat_mode_t compat_mode
)
781 HTMLEventObj
*event_obj
;
783 event_obj
= heap_alloc_zero(sizeof(*event_obj
));
787 event_obj
->IHTMLEventObj_iface
.lpVtbl
= &HTMLEventObjVtbl
;
789 event_obj
->event
= event
;
791 IDOMEvent_AddRef(&event
->IDOMEvent_iface
);
793 init_dispatch(&event_obj
->dispex
, (IUnknown
*)&event_obj
->IHTMLEventObj_iface
, &HTMLEventObj_dispex
, compat_mode
);
797 HRESULT
create_event_obj(compat_mode_t compat_mode
, IHTMLEventObj
**ret
)
799 HTMLEventObj
*event_obj
;
801 event_obj
= alloc_event_obj(NULL
, compat_mode
);
803 return E_OUTOFMEMORY
;
805 *ret
= &event_obj
->IHTMLEventObj_iface
;
809 static inline DOMEvent
*impl_from_IDOMEvent(IDOMEvent
*iface
)
811 return CONTAINING_RECORD(iface
, DOMEvent
, IDOMEvent_iface
);
814 static const IDOMEventVtbl DOMEventVtbl
;
816 static inline DOMEvent
*unsafe_impl_from_IDOMEvent(IDOMEvent
*iface
)
818 return iface
&& iface
->lpVtbl
== &DOMEventVtbl
? impl_from_IDOMEvent(iface
) : NULL
;
821 static HRESULT WINAPI
DOMEvent_QueryInterface(IDOMEvent
*iface
, REFIID riid
, void **ppv
)
823 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
825 TRACE("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
827 if(IsEqualGUID(&IID_IUnknown
, riid
))
828 *ppv
= &This
->IDOMEvent_iface
;
829 else if(IsEqualGUID(&IID_IDOMEvent
, riid
))
830 *ppv
= &This
->IDOMEvent_iface
;
831 else if(This
->ui_event
&& IsEqualGUID(&IID_IDOMUIEvent
, riid
))
832 *ppv
= &This
->IDOMUIEvent_iface
;
833 else if(This
->mouse_event
&& IsEqualGUID(&IID_IDOMMouseEvent
, riid
))
834 *ppv
= &This
->IDOMMouseEvent_iface
;
835 else if(This
->keyboard_event
&& IsEqualGUID(&IID_IDOMKeyboardEvent
, riid
))
836 *ppv
= &This
->IDOMKeyboardEvent_iface
;
837 else if(dispex_query_interface(&This
->dispex
, riid
, ppv
))
838 return *ppv
? S_OK
: E_NOINTERFACE
;
839 else if(!This
->query_interface
|| !(*ppv
= This
->query_interface(This
, riid
))) {
841 WARN("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
842 return E_NOINTERFACE
;
845 IUnknown_AddRef((IUnknown
*)*ppv
);
849 static ULONG WINAPI
DOMEvent_AddRef(IDOMEvent
*iface
)
851 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
852 LONG ref
= InterlockedIncrement(&This
->ref
);
854 TRACE("(%p) ref=%lu\n", This
, ref
);
859 static ULONG WINAPI
DOMEvent_Release(IDOMEvent
*iface
)
861 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
862 LONG ref
= InterlockedDecrement(&This
->ref
);
864 TRACE("(%p) ref=%lu\n", This
, ref
);
870 nsIDOMUIEvent_Release(This
->ui_event
);
871 if(This
->mouse_event
)
872 nsIDOMMouseEvent_Release(This
->mouse_event
);
873 if(This
->keyboard_event
)
874 nsIDOMKeyEvent_Release(This
->keyboard_event
);
876 IEventTarget_Release(&This
->target
->IEventTarget_iface
);
877 nsIDOMEvent_Release(This
->nsevent
);
878 release_dispex(&This
->dispex
);
879 heap_free(This
->type
);
886 static HRESULT WINAPI
DOMEvent_GetTypeInfoCount(IDOMEvent
*iface
, UINT
*pctinfo
)
888 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
889 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
892 static HRESULT WINAPI
DOMEvent_GetTypeInfo(IDOMEvent
*iface
, UINT iTInfo
,
893 LCID lcid
, ITypeInfo
**ppTInfo
)
895 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
896 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
899 static HRESULT WINAPI
DOMEvent_GetIDsOfNames(IDOMEvent
*iface
, REFIID riid
,
900 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
902 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
903 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
907 static HRESULT WINAPI
DOMEvent_Invoke(IDOMEvent
*iface
, DISPID dispIdMember
,
908 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
909 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
911 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
912 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
913 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
916 static HRESULT WINAPI
DOMEvent_get_bubbles(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
918 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
920 TRACE("(%p)->(%p)\n", This
, p
);
922 *p
= variant_bool(This
->bubbles
);
926 static HRESULT WINAPI
DOMEvent_get_cancelable(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
928 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
930 TRACE("(%p)->(%p)\n", This
, p
);
932 *p
= variant_bool(This
->cancelable
);
936 static HRESULT WINAPI
DOMEvent_get_currentTarget(IDOMEvent
*iface
, IEventTarget
**p
)
938 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
940 TRACE("(%p)->(%p)\n", This
, p
);
942 if(This
->current_target
)
943 IEventTarget_AddRef(*p
= &This
->current_target
->IEventTarget_iface
);
949 static HRESULT WINAPI
DOMEvent_get_defaultPrevented(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
951 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
953 TRACE("(%p)->(%p)\n", This
, p
);
955 *p
= variant_bool(This
->prevent_default
);
959 static HRESULT WINAPI
DOMEvent_get_eventPhase(IDOMEvent
*iface
, USHORT
*p
)
961 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
963 TRACE("(%p)->(%p)\n", This
, p
);
969 static HRESULT WINAPI
DOMEvent_get_target(IDOMEvent
*iface
, IEventTarget
**p
)
971 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
973 TRACE("(%p)->(%p)\n", This
, p
);
976 IEventTarget_AddRef(*p
= &This
->target
->IEventTarget_iface
);
982 static HRESULT WINAPI
DOMEvent_get_timeStamp(IDOMEvent
*iface
, ULONGLONG
*p
)
984 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
986 TRACE("(%p)->(%p)\n", This
, p
);
988 *p
= This
->time_stamp
;
992 static HRESULT WINAPI
DOMEvent_get_type(IDOMEvent
*iface
, BSTR
*p
)
994 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
996 TRACE("(%p)->(%p)\n", This
, p
);
999 *p
= SysAllocString(This
->type
);
1001 return E_OUTOFMEMORY
;
1009 #define nsIDOMEvent_InitEvent(_this,type,bubbles,cancelable) \
1010 ((void (WINAPI*)(void*,nsIDOMEvent*,const nsAString*,cpp_bool,cpp_bool)) \
1011 &call_thiscall_func)((_this)->lpVtbl->InitEvent,_this,type,bubbles,cancelable)
1015 static HRESULT WINAPI
DOMEvent_initEvent(IDOMEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
, VARIANT_BOOL cancelable
)
1017 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1020 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_w(type
), can_bubble
, cancelable
);
1023 TRACE("called on already dispatched event\n");
1027 heap_free(This
->type
);
1028 This
->type
= heap_strdupW(type
);
1030 return E_OUTOFMEMORY
;
1031 This
->event_id
= str_to_eid(type
);
1033 This
->bubbles
= !!can_bubble
;
1034 This
->cancelable
= !!cancelable
;
1036 nsAString_InitDepend(&nsstr
, type
);
1037 nsIDOMEvent_InitEvent(This
->nsevent
, &nsstr
, This
->bubbles
, This
->cancelable
);
1038 nsAString_Finish(&nsstr
);
1043 static HRESULT WINAPI
DOMEvent_preventDefault(IDOMEvent
*iface
)
1045 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1047 TRACE("(%p)\n", This
);
1049 if(This
->current_target
&& This
->cancelable
) {
1050 This
->prevent_default
= TRUE
;
1051 nsIDOMEvent_PreventDefault(This
->nsevent
);
1056 static HRESULT WINAPI
DOMEvent_stopPropagation(IDOMEvent
*iface
)
1058 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1060 TRACE("(%p)\n", This
);
1062 This
->stop_propagation
= TRUE
;
1063 nsIDOMEvent_StopPropagation(This
->nsevent
);
1067 static HRESULT WINAPI
DOMEvent_stopImmediatePropagation(IDOMEvent
*iface
)
1069 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1071 TRACE("(%p)\n", This
);
1073 This
->stop_immediate_propagation
= This
->stop_propagation
= TRUE
;
1074 nsIDOMEvent_StopImmediatePropagation(This
->nsevent
);
1078 static HRESULT WINAPI
DOMEvent_get_isTrusted(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
1080 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1082 TRACE("(%p)->(%p)\n", This
, p
);
1084 *p
= variant_bool(This
->trusted
);
1088 static HRESULT WINAPI
DOMEvent_put_cancelBubble(IDOMEvent
*iface
, VARIANT_BOOL v
)
1090 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1091 FIXME("(%p)->(%x)\n", This
, v
);
1095 static HRESULT WINAPI
DOMEvent_get_cancelBubble(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
1097 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1098 FIXME("(%p)->(%p)\n", This
, p
);
1102 static HRESULT WINAPI
DOMEvent_get_srcElement(IDOMEvent
*iface
, IHTMLElement
**p
)
1104 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1106 TRACE("(%p)->(%p)\n", This
, p
);
1109 IDispatchEx_QueryInterface(&This
->target
->dispex
.IDispatchEx_iface
, &IID_IHTMLElement
, (void**)p
);
1115 static const IDOMEventVtbl DOMEventVtbl
= {
1116 DOMEvent_QueryInterface
,
1119 DOMEvent_GetTypeInfoCount
,
1120 DOMEvent_GetTypeInfo
,
1121 DOMEvent_GetIDsOfNames
,
1123 DOMEvent_get_bubbles
,
1124 DOMEvent_get_cancelable
,
1125 DOMEvent_get_currentTarget
,
1126 DOMEvent_get_defaultPrevented
,
1127 DOMEvent_get_eventPhase
,
1128 DOMEvent_get_target
,
1129 DOMEvent_get_timeStamp
,
1132 DOMEvent_preventDefault
,
1133 DOMEvent_stopPropagation
,
1134 DOMEvent_stopImmediatePropagation
,
1135 DOMEvent_get_isTrusted
,
1136 DOMEvent_put_cancelBubble
,
1137 DOMEvent_get_cancelBubble
,
1138 DOMEvent_get_srcElement
1141 static inline DOMEvent
*impl_from_IDOMUIEvent(IDOMUIEvent
*iface
)
1143 return CONTAINING_RECORD(iface
, DOMEvent
, IDOMUIEvent_iface
);
1146 static HRESULT WINAPI
DOMUIEvent_QueryInterface(IDOMUIEvent
*iface
, REFIID riid
, void **ppv
)
1148 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1149 return IDOMEvent_QueryInterface(&This
->IDOMEvent_iface
, riid
, ppv
);
1152 static ULONG WINAPI
DOMUIEvent_AddRef(IDOMUIEvent
*iface
)
1154 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1155 return IDOMEvent_AddRef(&This
->IDOMEvent_iface
);
1158 static ULONG WINAPI
DOMUIEvent_Release(IDOMUIEvent
*iface
)
1160 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1161 return IDOMEvent_Release(&This
->IDOMEvent_iface
);
1164 static HRESULT WINAPI
DOMUIEvent_GetTypeInfoCount(IDOMUIEvent
*iface
, UINT
*pctinfo
)
1166 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1167 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
1170 static HRESULT WINAPI
DOMUIEvent_GetTypeInfo(IDOMUIEvent
*iface
, UINT iTInfo
,
1171 LCID lcid
, ITypeInfo
**ppTInfo
)
1173 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1174 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1177 static HRESULT WINAPI
DOMUIEvent_GetIDsOfNames(IDOMUIEvent
*iface
, REFIID riid
,
1178 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1180 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1181 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1185 static HRESULT WINAPI
DOMUIEvent_Invoke(IDOMUIEvent
*iface
, DISPID dispIdMember
,
1186 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1187 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1189 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1190 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1191 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1194 static HRESULT WINAPI
DOMUIEvent_get_view(IDOMUIEvent
*iface
, IHTMLWindow2
**p
)
1196 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1197 mozIDOMWindowProxy
*moz_window
;
1198 HTMLOuterWindow
*view
= NULL
;
1201 TRACE("(%p)->(%p)\n", This
, p
);
1203 nsres
= nsIDOMUIEvent_GetView(This
->ui_event
, &moz_window
);
1204 if(NS_FAILED(nsres
))
1208 view
= mozwindow_to_window(moz_window
);
1209 mozIDOMWindowProxy_Release(moz_window
);
1212 IHTMLWindow2_AddRef((*p
= &view
->base
.inner_window
->base
.IHTMLWindow2_iface
));
1218 static HRESULT WINAPI
DOMUIEvent_get_detail(IDOMUIEvent
*iface
, LONG
*p
)
1220 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1224 TRACE("(%p)->(%p)\n", This
, p
);
1226 nsres
= nsIDOMUIEvent_GetDetail(This
->ui_event
, &detail
);
1227 if(NS_FAILED(nsres
))
1234 static HRESULT WINAPI
DOMUIEvent_initUIEvent(IDOMUIEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
1235 VARIANT_BOOL cancelable
, IHTMLWindow2
*view
, LONG detail
)
1237 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1242 TRACE("(%p)->(%s %x %x %p %lx)\n", This
, debugstr_w(type
), can_bubble
, cancelable
, view
, detail
);
1245 TRACE("called on already dispatched event\n");
1250 FIXME("view argument is not supported\n");
1252 hres
= IDOMEvent_initEvent(&This
->IDOMEvent_iface
, type
, can_bubble
, cancelable
);
1256 nsAString_InitDepend(&type_str
, type
);
1257 nsres
= nsIDOMUIEvent_InitUIEvent(This
->ui_event
, &type_str
, !!can_bubble
, !!cancelable
,
1258 NULL
/* FIXME */, detail
);
1259 nsAString_Finish(&type_str
);
1260 if(NS_FAILED(nsres
)) {
1261 FIXME("InitUIEvent failed: %08lx\n", nsres
);
1268 static const IDOMUIEventVtbl DOMUIEventVtbl
= {
1269 DOMUIEvent_QueryInterface
,
1272 DOMUIEvent_GetTypeInfoCount
,
1273 DOMUIEvent_GetTypeInfo
,
1274 DOMUIEvent_GetIDsOfNames
,
1276 DOMUIEvent_get_view
,
1277 DOMUIEvent_get_detail
,
1278 DOMUIEvent_initUIEvent
1281 static inline DOMEvent
*impl_from_IDOMMouseEvent(IDOMMouseEvent
*iface
)
1283 return CONTAINING_RECORD(iface
, DOMEvent
, IDOMMouseEvent_iface
);
1286 static HRESULT WINAPI
DOMMouseEvent_QueryInterface(IDOMMouseEvent
*iface
, REFIID riid
, void **ppv
)
1288 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1289 return IDOMEvent_QueryInterface(&This
->IDOMEvent_iface
, riid
, ppv
);
1292 static ULONG WINAPI
DOMMouseEvent_AddRef(IDOMMouseEvent
*iface
)
1294 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1295 return IDOMEvent_AddRef(&This
->IDOMEvent_iface
);
1298 static ULONG WINAPI
DOMMouseEvent_Release(IDOMMouseEvent
*iface
)
1300 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1301 return IDOMEvent_Release(&This
->IDOMEvent_iface
);
1304 static HRESULT WINAPI
DOMMouseEvent_GetTypeInfoCount(IDOMMouseEvent
*iface
, UINT
*pctinfo
)
1306 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1307 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
1310 static HRESULT WINAPI
DOMMouseEvent_GetTypeInfo(IDOMMouseEvent
*iface
, UINT iTInfo
,
1311 LCID lcid
, ITypeInfo
**ppTInfo
)
1313 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1314 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1317 static HRESULT WINAPI
DOMMouseEvent_GetIDsOfNames(IDOMMouseEvent
*iface
, REFIID riid
,
1318 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1320 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1321 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1325 static HRESULT WINAPI
DOMMouseEvent_Invoke(IDOMMouseEvent
*iface
, DISPID dispIdMember
,
1326 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1327 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1329 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1330 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1331 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1334 static HRESULT WINAPI
DOMMouseEvent_get_screenX(IDOMMouseEvent
*iface
, LONG
*p
)
1336 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1340 TRACE("(%p)->(%p)\n", This
, p
);
1342 nsres
= nsIDOMMouseEvent_GetScreenX(This
->mouse_event
, &screen_x
);
1343 if(NS_FAILED(nsres
))
1350 static HRESULT WINAPI
DOMMouseEvent_get_screenY(IDOMMouseEvent
*iface
, LONG
*p
)
1352 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1356 TRACE("(%p)->(%p)\n", This
, p
);
1358 nsres
= nsIDOMMouseEvent_GetScreenY(This
->mouse_event
, &screen_y
);
1359 if(NS_FAILED(nsres
))
1366 static HRESULT WINAPI
DOMMouseEvent_get_clientX(IDOMMouseEvent
*iface
, LONG
*p
)
1368 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1372 TRACE("(%p)->(%p)\n", This
, p
);
1374 nsres
= nsIDOMMouseEvent_GetClientX(This
->mouse_event
, &client_x
);
1375 if(NS_FAILED(nsres
))
1382 static HRESULT WINAPI
DOMMouseEvent_get_clientY(IDOMMouseEvent
*iface
, LONG
*p
)
1384 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1388 TRACE("(%p)->(%p)\n", This
, p
);
1390 nsres
= nsIDOMMouseEvent_GetClientY(This
->mouse_event
, &client_y
);
1391 if(NS_FAILED(nsres
))
1398 static HRESULT WINAPI
DOMMouseEvent_get_ctrlKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1400 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1404 TRACE("(%p)->(%p)\n", This
, p
);
1406 nsres
= nsIDOMMouseEvent_GetCtrlKey(This
->mouse_event
, &r
);
1407 if(NS_FAILED(nsres
))
1410 *p
= variant_bool(r
);
1414 static HRESULT WINAPI
DOMMouseEvent_get_shiftKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1416 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1420 TRACE("(%p)->(%p)\n", This
, p
);
1422 nsres
= nsIDOMMouseEvent_GetShiftKey(This
->mouse_event
, &r
);
1423 if(NS_FAILED(nsres
))
1426 *p
= variant_bool(r
);
1430 static HRESULT WINAPI
DOMMouseEvent_get_altKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1432 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1436 TRACE("(%p)->(%p)\n", This
, p
);
1438 nsres
= nsIDOMMouseEvent_GetAltKey(This
->mouse_event
, &r
);
1439 if(NS_FAILED(nsres
))
1442 *p
= variant_bool(r
);
1446 static HRESULT WINAPI
DOMMouseEvent_get_metaKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1448 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1452 TRACE("(%p)->(%p)\n", This
, p
);
1454 nsres
= nsIDOMMouseEvent_GetMetaKey(This
->mouse_event
, &r
);
1455 if(NS_FAILED(nsres
))
1458 *p
= variant_bool(r
);
1462 static HRESULT WINAPI
DOMMouseEvent_get_button(IDOMMouseEvent
*iface
, USHORT
*p
)
1464 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1468 TRACE("(%p)->(%p)\n", This
, p
);
1470 nsres
= nsIDOMMouseEvent_GetButton(This
->mouse_event
, &r
);
1471 if(NS_FAILED(nsres
))
1478 static HRESULT WINAPI
DOMMouseEvent_get_relatedTarget(IDOMMouseEvent
*iface
, IEventTarget
**p
)
1480 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1481 nsIDOMEventTarget
*related_target
;
1482 nsIDOMNode
*target_node
;
1487 TRACE("(%p)->(%p)\n", This
, p
);
1489 nsres
= nsIDOMMouseEvent_GetRelatedTarget(This
->mouse_event
, &related_target
);
1490 if(NS_FAILED(nsres
))
1493 if(!related_target
) {
1498 nsres
= nsIDOMEventTarget_QueryInterface(related_target
, &IID_nsIDOMNode
, (void**)&target_node
);
1499 nsIDOMEventTarget_Release(related_target
);
1500 if(NS_FAILED(nsres
)) {
1501 FIXME("Only node targets supported\n");
1505 hres
= get_node(target_node
, TRUE
, &node
);
1506 nsIDOMNode_Release(target_node
);
1510 *p
= &node
->event_target
.IEventTarget_iface
;
1514 static HRESULT WINAPI
DOMMouseEvent_initMouseEvent(IDOMMouseEvent
*iface
, BSTR type
,
1515 VARIANT_BOOL can_bubble
, VARIANT_BOOL cancelable
, IHTMLWindow2
*view
, LONG detail
,
1516 LONG screen_x
, LONG screen_y
, LONG client_x
, LONG client_y
, VARIANT_BOOL ctrl_key
,
1517 VARIANT_BOOL alt_key
, VARIANT_BOOL shift_key
, VARIANT_BOOL meta_key
, USHORT button
,
1518 IEventTarget
*related_target
)
1520 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1521 nsIDOMEventTarget
*nstarget
= NULL
;
1526 TRACE("(%p)->(%s %x %x %p %ld %ld %ld %ld %ld %x %x %x %x %u %p)\n", This
, debugstr_w(type
),
1527 can_bubble
, cancelable
, view
, detail
, screen_x
, screen_y
, client_x
, client_y
,
1528 ctrl_key
, alt_key
, shift_key
, meta_key
, button
, related_target
);
1531 TRACE("called on already dispatched event\n");
1536 FIXME("view argument is not supported\n");
1538 if(related_target
) {
1539 hres
= get_gecko_target(related_target
, &nstarget
);
1544 hres
= IDOMEvent_initEvent(&This
->IDOMEvent_iface
, type
, can_bubble
, cancelable
);
1545 if(SUCCEEDED(hres
)) {
1546 nsAString_InitDepend(&type_str
, type
);
1547 nsres
= nsIDOMMouseEvent_InitMouseEvent(This
->mouse_event
, &type_str
, can_bubble
, cancelable
,
1548 NULL
/* FIXME */, detail
, screen_x
, screen_y
,
1549 client_x
, client_y
, !!ctrl_key
, !!alt_key
, !!shift_key
,
1550 !!meta_key
, button
, nstarget
);
1551 nsAString_Finish(&type_str
);
1552 if(NS_FAILED(nsres
)) {
1553 FIXME("InitMouseEvent failed: %08lx\n", nsres
);
1559 nsIDOMEventTarget_Release(nstarget
);
1563 static HRESULT WINAPI
DOMMouseEvent_getModifierState(IDOMMouseEvent
*iface
, BSTR key
,
1564 VARIANT_BOOL
*activated
)
1566 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1567 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(key
), activated
);
1571 static HRESULT WINAPI
DOMMouseEvent_get_buttons(IDOMMouseEvent
*iface
, USHORT
*p
)
1573 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1577 TRACE("(%p)->(%p)\n", This
, p
);
1579 nsres
= nsIDOMMouseEvent_GetButtons(This
->mouse_event
, &r
);
1580 if(NS_FAILED(nsres
))
1587 static HRESULT WINAPI
DOMMouseEvent_get_fromElement(IDOMMouseEvent
*iface
, IHTMLElement
**p
)
1589 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1590 IEventTarget
*related_target
= NULL
;
1592 TRACE("(%p)->(%p)\n", This
, p
);
1594 if(This
->event_id
!= EVENTID_LAST
) {
1595 HRESULT hres
= S_OK
;
1596 if(event_info
[This
->event_id
].flags
& EVENT_MOUSE_FROM_RELATED
)
1597 hres
= IDOMMouseEvent_get_relatedTarget(&This
->IDOMMouseEvent_iface
, &related_target
);
1598 else if(event_info
[This
->event_id
].flags
& EVENT_MOUSE_TO_RELATED
)
1599 hres
= IDOMEvent_get_target(&This
->IDOMEvent_iface
, &related_target
);
1604 if(!related_target
) {
1609 IEventTarget_QueryInterface(related_target
, &IID_IHTMLElement
, (void**)p
);
1613 static HRESULT WINAPI
DOMMouseEvent_get_toElement(IDOMMouseEvent
*iface
, IHTMLElement
**p
)
1615 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1616 IEventTarget
*related_target
= NULL
;
1618 TRACE("(%p)->(%p)\n", This
, p
);
1620 if(This
->event_id
!= EVENTID_LAST
) {
1621 HRESULT hres
= S_OK
;
1622 if(event_info
[This
->event_id
].flags
& EVENT_MOUSE_TO_RELATED
)
1623 hres
= IDOMMouseEvent_get_relatedTarget(&This
->IDOMMouseEvent_iface
, &related_target
);
1624 else if(event_info
[This
->event_id
].flags
& EVENT_MOUSE_FROM_RELATED
)
1625 hres
= IDOMEvent_get_target(&This
->IDOMEvent_iface
, &related_target
);
1630 if(!related_target
) {
1635 IEventTarget_QueryInterface(related_target
, &IID_IHTMLElement
, (void**)p
);
1639 static HRESULT WINAPI
DOMMouseEvent_get_x(IDOMMouseEvent
*iface
, LONG
*p
)
1641 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1642 FIXME("(%p)->(%p)\n", This
, p
);
1646 static HRESULT WINAPI
DOMMouseEvent_get_y(IDOMMouseEvent
*iface
, LONG
*p
)
1648 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1649 FIXME("(%p)->(%p)\n", This
, p
);
1653 static HRESULT WINAPI
DOMMouseEvent_get_offsetX(IDOMMouseEvent
*iface
, LONG
*p
)
1655 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1657 FIXME("(%p)->(%p) returning 0\n", This
, p
);
1663 static HRESULT WINAPI
DOMMouseEvent_get_offsetY(IDOMMouseEvent
*iface
, LONG
*p
)
1665 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1667 FIXME("(%p)->(%p) returning 0\n", This
, p
);
1673 static HRESULT WINAPI
DOMMouseEvent_get_pageX(IDOMMouseEvent
*iface
, LONG
*p
)
1675 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1679 TRACE("(%p)->(%p)\n", This
, p
);
1681 nsres
= nsIDOMMouseEvent_GetPageX(This
->mouse_event
, &r
);
1682 if(NS_FAILED(nsres
))
1689 static HRESULT WINAPI
DOMMouseEvent_get_pageY(IDOMMouseEvent
*iface
, LONG
*p
)
1691 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1695 TRACE("(%p)->(%p)\n", This
, p
);
1697 nsres
= nsIDOMMouseEvent_GetPageY(This
->mouse_event
, &r
);
1698 if(NS_FAILED(nsres
))
1705 static HRESULT WINAPI
DOMMouseEvent_get_layerX(IDOMMouseEvent
*iface
, LONG
*p
)
1707 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1711 TRACE("(%p)->(%p)\n", This
, p
);
1713 nsres
= nsIDOMMouseEvent_GetLayerX(This
->mouse_event
, &r
);
1714 if(NS_FAILED(nsres
))
1721 static HRESULT WINAPI
DOMMouseEvent_get_layerY(IDOMMouseEvent
*iface
, LONG
*p
)
1723 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1727 TRACE("(%p)->(%p)\n", This
, p
);
1729 nsres
= nsIDOMMouseEvent_GetLayerY(This
->mouse_event
, &r
);
1730 if(NS_FAILED(nsres
))
1737 static HRESULT WINAPI
DOMMouseEvent_get_which(IDOMMouseEvent
*iface
, USHORT
*p
)
1739 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1743 TRACE("(%p)->(%p)\n", This
, p
);
1745 nsres
= nsIDOMMouseEvent_GetWhich(This
->mouse_event
, &r
);
1746 if(NS_FAILED(nsres
))
1753 static const IDOMMouseEventVtbl DOMMouseEventVtbl
= {
1754 DOMMouseEvent_QueryInterface
,
1755 DOMMouseEvent_AddRef
,
1756 DOMMouseEvent_Release
,
1757 DOMMouseEvent_GetTypeInfoCount
,
1758 DOMMouseEvent_GetTypeInfo
,
1759 DOMMouseEvent_GetIDsOfNames
,
1760 DOMMouseEvent_Invoke
,
1761 DOMMouseEvent_get_screenX
,
1762 DOMMouseEvent_get_screenY
,
1763 DOMMouseEvent_get_clientX
,
1764 DOMMouseEvent_get_clientY
,
1765 DOMMouseEvent_get_ctrlKey
,
1766 DOMMouseEvent_get_shiftKey
,
1767 DOMMouseEvent_get_altKey
,
1768 DOMMouseEvent_get_metaKey
,
1769 DOMMouseEvent_get_button
,
1770 DOMMouseEvent_get_relatedTarget
,
1771 DOMMouseEvent_initMouseEvent
,
1772 DOMMouseEvent_getModifierState
,
1773 DOMMouseEvent_get_buttons
,
1774 DOMMouseEvent_get_fromElement
,
1775 DOMMouseEvent_get_toElement
,
1776 DOMMouseEvent_get_x
,
1777 DOMMouseEvent_get_y
,
1778 DOMMouseEvent_get_offsetX
,
1779 DOMMouseEvent_get_offsetY
,
1780 DOMMouseEvent_get_pageX
,
1781 DOMMouseEvent_get_pageY
,
1782 DOMMouseEvent_get_layerX
,
1783 DOMMouseEvent_get_layerY
,
1784 DOMMouseEvent_get_which
1787 static inline DOMEvent
*impl_from_IDOMKeyboardEvent(IDOMKeyboardEvent
*iface
)
1789 return CONTAINING_RECORD(iface
, DOMEvent
, IDOMKeyboardEvent_iface
);
1792 static HRESULT WINAPI
DOMKeyboardEvent_QueryInterface(IDOMKeyboardEvent
*iface
, REFIID riid
, void **ppv
)
1794 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1795 return IDOMEvent_QueryInterface(&This
->IDOMEvent_iface
, riid
, ppv
);
1798 static ULONG WINAPI
DOMKeyboardEvent_AddRef(IDOMKeyboardEvent
*iface
)
1800 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1801 return IDOMEvent_AddRef(&This
->IDOMEvent_iface
);
1804 static ULONG WINAPI
DOMKeyboardEvent_Release(IDOMKeyboardEvent
*iface
)
1806 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1807 return IDOMEvent_Release(&This
->IDOMEvent_iface
);
1810 static HRESULT WINAPI
DOMKeyboardEvent_GetTypeInfoCount(IDOMKeyboardEvent
*iface
, UINT
*pctinfo
)
1812 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1813 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
1816 static HRESULT WINAPI
DOMKeyboardEvent_GetTypeInfo(IDOMKeyboardEvent
*iface
, UINT iTInfo
,
1817 LCID lcid
, ITypeInfo
**ppTInfo
)
1819 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1820 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1823 static HRESULT WINAPI
DOMKeyboardEvent_GetIDsOfNames(IDOMKeyboardEvent
*iface
, REFIID riid
,
1824 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1826 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1827 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1831 static HRESULT WINAPI
DOMKeyboardEvent_Invoke(IDOMKeyboardEvent
*iface
, DISPID dispIdMember
,
1832 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1833 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1835 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1836 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1837 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1840 static HRESULT WINAPI
DOMKeyboardEvent_get_key(IDOMKeyboardEvent
*iface
, BSTR
*p
)
1842 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1846 TRACE("(%p)->(%p)\n", This
, p
);
1849 nsAString_Init(&key_str
, NULL
);
1850 nsres
= nsIDOMKeyEvent_GetKey(This
->keyboard_event
, &key_str
);
1851 return return_nsstr(nsres
, &key_str
, p
);
1854 static HRESULT WINAPI
DOMKeyboardEvent_get_location(IDOMKeyboardEvent
*iface
, ULONG
*p
)
1856 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1860 TRACE("(%p)->(%p)\n", This
, p
);
1862 nsres
= nsIDOMKeyEvent_GetLocation(This
->keyboard_event
, &r
);
1863 if(NS_FAILED(nsres
))
1870 static HRESULT WINAPI
DOMKeyboardEvent_get_ctrlKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1872 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1876 TRACE("(%p)->(%p)\n", This
, p
);
1878 nsres
= nsIDOMKeyEvent_GetCtrlKey(This
->keyboard_event
, &r
);
1879 if(NS_FAILED(nsres
))
1882 *p
= variant_bool(r
);
1886 static HRESULT WINAPI
DOMKeyboardEvent_get_shiftKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1888 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1892 TRACE("(%p)->(%p)\n", This
, p
);
1894 nsres
= nsIDOMKeyEvent_GetShiftKey(This
->keyboard_event
, &r
);
1895 if(NS_FAILED(nsres
))
1898 *p
= variant_bool(r
);
1902 static HRESULT WINAPI
DOMKeyboardEvent_get_altKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1904 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1908 TRACE("(%p)->(%p)\n", This
, p
);
1910 nsres
= nsIDOMKeyEvent_GetAltKey(This
->keyboard_event
, &r
);
1911 if(NS_FAILED(nsres
))
1914 *p
= variant_bool(r
);
1918 static HRESULT WINAPI
DOMKeyboardEvent_get_metaKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1920 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1924 TRACE("(%p)->(%p)\n", This
, p
);
1926 nsres
= nsIDOMKeyEvent_GetMetaKey(This
->keyboard_event
, &r
);
1927 if(NS_FAILED(nsres
))
1930 *p
= variant_bool(r
);
1934 static HRESULT WINAPI
DOMKeyboardEvent_get_repeat(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1936 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1940 TRACE("(%p)->(%p)\n", This
, p
);
1942 nsres
= nsIDOMKeyEvent_GetRepeat(This
->keyboard_event
, &r
);
1943 if(NS_FAILED(nsres
))
1946 *p
= variant_bool(r
);
1950 static HRESULT WINAPI
DOMKeyboardEvent_getModifierState(IDOMKeyboardEvent
*iface
, BSTR key
,
1951 VARIANT_BOOL
*state
)
1953 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1954 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(key
), state
);
1958 static HRESULT WINAPI
DOMKeyboardEvent_initKeyboardEvent(IDOMKeyboardEvent
*iface
, BSTR type
,
1959 VARIANT_BOOL can_bubble
, VARIANT_BOOL cancelable
, IHTMLWindow2
*view
, BSTR key
,
1960 ULONG location
, BSTR modifiers_list
, VARIANT_BOOL repeat
, BSTR locale
)
1962 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1963 FIXME("(%p)->(%s %x %x %p %s %lu %s %x %s)\n", This
, debugstr_w(type
), can_bubble
,
1964 cancelable
, view
, debugstr_w(key
), location
, debugstr_w(modifiers_list
),
1965 repeat
, debugstr_w(locale
));
1969 static HRESULT WINAPI
DOMKeyboardEvent_get_keyCode(IDOMKeyboardEvent
*iface
, LONG
*p
)
1971 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1975 TRACE("(%p)->(%p)\n", This
, p
);
1977 nsres
= nsIDOMKeyEvent_GetKeyCode(This
->keyboard_event
, &r
);
1978 if(NS_FAILED(nsres
))
1985 static HRESULT WINAPI
DOMKeyboardEvent_get_charCode(IDOMKeyboardEvent
*iface
, LONG
*p
)
1987 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1991 TRACE("(%p)->(%p)\n", This
, p
);
1993 nsres
= nsIDOMKeyEvent_GetKeyCode(This
->keyboard_event
, &r
);
1994 if(NS_FAILED(nsres
))
2001 static HRESULT WINAPI
DOMKeyboardEvent_get_which(IDOMKeyboardEvent
*iface
, LONG
*p
)
2003 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2007 TRACE("(%p)->(%p)\n", This
, p
);
2009 nsres
= nsIDOMKeyEvent_GetWhich(This
->keyboard_event
, &r
);
2010 if(NS_FAILED(nsres
))
2017 static HRESULT WINAPI
DOMKeyboardEvent_get_char(IDOMKeyboardEvent
*iface
, VARIANT
*p
)
2019 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2020 FIXME("(%p)->(%p)\n", This
, p
);
2024 static HRESULT WINAPI
DOMKeyboardEvent_get_locale(IDOMKeyboardEvent
*iface
, BSTR
*p
)
2026 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2027 FIXME("(%p)->(%p)\n", This
, p
);
2031 static const IDOMKeyboardEventVtbl DOMKeyboardEventVtbl
= {
2032 DOMKeyboardEvent_QueryInterface
,
2033 DOMKeyboardEvent_AddRef
,
2034 DOMKeyboardEvent_Release
,
2035 DOMKeyboardEvent_GetTypeInfoCount
,
2036 DOMKeyboardEvent_GetTypeInfo
,
2037 DOMKeyboardEvent_GetIDsOfNames
,
2038 DOMKeyboardEvent_Invoke
,
2039 DOMKeyboardEvent_get_key
,
2040 DOMKeyboardEvent_get_location
,
2041 DOMKeyboardEvent_get_ctrlKey
,
2042 DOMKeyboardEvent_get_shiftKey
,
2043 DOMKeyboardEvent_get_altKey
,
2044 DOMKeyboardEvent_get_metaKey
,
2045 DOMKeyboardEvent_get_repeat
,
2046 DOMKeyboardEvent_getModifierState
,
2047 DOMKeyboardEvent_initKeyboardEvent
,
2048 DOMKeyboardEvent_get_keyCode
,
2049 DOMKeyboardEvent_get_charCode
,
2050 DOMKeyboardEvent_get_which
,
2051 DOMKeyboardEvent_get_char
,
2052 DOMKeyboardEvent_get_locale
2057 IDOMCustomEvent IDOMCustomEvent_iface
;
2061 static inline DOMCustomEvent
*impl_from_IDOMCustomEvent(IDOMCustomEvent
*iface
)
2063 return CONTAINING_RECORD(iface
, DOMCustomEvent
, IDOMCustomEvent_iface
);
2066 static HRESULT WINAPI
DOMCustomEvent_QueryInterface(IDOMCustomEvent
*iface
, REFIID riid
, void **ppv
)
2068 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2069 return IDOMEvent_QueryInterface(&This
->event
.IDOMEvent_iface
, riid
, ppv
);
2072 static ULONG WINAPI
DOMCustomEvent_AddRef(IDOMCustomEvent
*iface
)
2074 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2075 return IDOMEvent_AddRef(&This
->event
.IDOMEvent_iface
);
2078 static ULONG WINAPI
DOMCustomEvent_Release(IDOMCustomEvent
*iface
)
2080 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2081 return IDOMEvent_Release(&This
->event
.IDOMEvent_iface
);
2084 static HRESULT WINAPI
DOMCustomEvent_GetTypeInfoCount(IDOMCustomEvent
*iface
, UINT
*pctinfo
)
2086 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2087 return IDispatchEx_GetTypeInfoCount(&This
->event
.dispex
.IDispatchEx_iface
, pctinfo
);
2090 static HRESULT WINAPI
DOMCustomEvent_GetTypeInfo(IDOMCustomEvent
*iface
, UINT iTInfo
,
2091 LCID lcid
, ITypeInfo
**ppTInfo
)
2093 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2094 return IDispatchEx_GetTypeInfo(&This
->event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
2097 static HRESULT WINAPI
DOMCustomEvent_GetIDsOfNames(IDOMCustomEvent
*iface
, REFIID riid
,
2098 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2100 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2101 return IDispatchEx_GetIDsOfNames(&This
->event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
2105 static HRESULT WINAPI
DOMCustomEvent_Invoke(IDOMCustomEvent
*iface
, DISPID dispIdMember
,
2106 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2107 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2109 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2110 return IDispatchEx_Invoke(&This
->event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
2111 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2114 static HRESULT WINAPI
DOMCustomEvent_get_detail(IDOMCustomEvent
*iface
, VARIANT
*p
)
2116 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2118 TRACE("(%p)->(%p)\n", This
, p
);
2121 return VariantCopy(p
, &This
->detail
);
2124 static HRESULT WINAPI
DOMCustomEvent_initCustomEvent(IDOMCustomEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
2125 VARIANT_BOOL cancelable
, VARIANT
*detail
)
2127 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2130 TRACE("(%p)->(%s %x %x %s)\n", This
, debugstr_w(type
), can_bubble
, cancelable
, debugstr_variant(detail
));
2132 hres
= IDOMEvent_initEvent(&This
->event
.IDOMEvent_iface
, type
, can_bubble
, cancelable
);
2136 return VariantCopy(&This
->detail
, detail
);
2139 static const IDOMCustomEventVtbl DOMCustomEventVtbl
= {
2140 DOMCustomEvent_QueryInterface
,
2141 DOMCustomEvent_AddRef
,
2142 DOMCustomEvent_Release
,
2143 DOMCustomEvent_GetTypeInfoCount
,
2144 DOMCustomEvent_GetTypeInfo
,
2145 DOMCustomEvent_GetIDsOfNames
,
2146 DOMCustomEvent_Invoke
,
2147 DOMCustomEvent_get_detail
,
2148 DOMCustomEvent_initCustomEvent
2151 static DOMCustomEvent
*DOMCustomEvent_from_DOMEvent(DOMEvent
*event
)
2153 return CONTAINING_RECORD(event
, DOMCustomEvent
, event
);
2156 static void *DOMCustomEvent_query_interface(DOMEvent
*event
, REFIID riid
)
2158 DOMCustomEvent
*custom_event
= DOMCustomEvent_from_DOMEvent(event
);
2159 if(IsEqualGUID(&IID_IDOMCustomEvent
, riid
))
2160 return &custom_event
->IDOMCustomEvent_iface
;
2164 static void DOMCustomEvent_destroy(DOMEvent
*event
)
2166 DOMCustomEvent
*custom_event
= DOMCustomEvent_from_DOMEvent(event
);
2167 VariantClear(&custom_event
->detail
);
2172 IDOMMessageEvent IDOMMessageEvent_iface
;
2176 static inline DOMMessageEvent
*impl_from_IDOMMessageEvent(IDOMMessageEvent
*iface
)
2178 return CONTAINING_RECORD(iface
, DOMMessageEvent
, IDOMMessageEvent_iface
);
2181 static HRESULT WINAPI
DOMMessageEvent_QueryInterface(IDOMMessageEvent
*iface
, REFIID riid
, void **ppv
)
2183 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2184 return IDOMEvent_QueryInterface(&This
->event
.IDOMEvent_iface
, riid
, ppv
);
2187 static ULONG WINAPI
DOMMessageEvent_AddRef(IDOMMessageEvent
*iface
)
2189 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2190 return IDOMEvent_AddRef(&This
->event
.IDOMEvent_iface
);
2193 static ULONG WINAPI
DOMMessageEvent_Release(IDOMMessageEvent
*iface
)
2195 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2196 return IDOMEvent_Release(&This
->event
.IDOMEvent_iface
);
2199 static HRESULT WINAPI
DOMMessageEvent_GetTypeInfoCount(IDOMMessageEvent
*iface
, UINT
*pctinfo
)
2201 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2202 return IDispatchEx_GetTypeInfoCount(&This
->event
.dispex
.IDispatchEx_iface
, pctinfo
);
2205 static HRESULT WINAPI
DOMMessageEvent_GetTypeInfo(IDOMMessageEvent
*iface
, UINT iTInfo
,
2206 LCID lcid
, ITypeInfo
**ppTInfo
)
2208 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2209 return IDispatchEx_GetTypeInfo(&This
->event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
2212 static HRESULT WINAPI
DOMMessageEvent_GetIDsOfNames(IDOMMessageEvent
*iface
, REFIID riid
,
2213 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2215 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2216 return IDispatchEx_GetIDsOfNames(&This
->event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
2220 static HRESULT WINAPI
DOMMessageEvent_Invoke(IDOMMessageEvent
*iface
, DISPID dispIdMember
,
2221 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2222 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2224 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2225 return IDispatchEx_Invoke(&This
->event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
2226 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2229 static HRESULT WINAPI
DOMMessageEvent_get_data(IDOMMessageEvent
*iface
, BSTR
*p
)
2231 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2233 TRACE("(%p)->(%p)\n", This
, p
);
2235 return (*p
= SysAllocString(This
->data
)) ? S_OK
: E_OUTOFMEMORY
;
2238 static HRESULT WINAPI
DOMMessageEvent_get_origin(IDOMMessageEvent
*iface
, BSTR
*p
)
2240 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2241 FIXME("(%p)->(%p)\n", This
, p
);
2245 static HRESULT WINAPI
DOMMessageEvent_get_source(IDOMMessageEvent
*iface
, IHTMLWindow2
**p
)
2247 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2248 FIXME("(%p)->(%p)\n", This
, p
);
2252 static HRESULT WINAPI
DOMMessageEvent_initMessageEvent(IDOMMessageEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
2253 VARIANT_BOOL cancelable
, BSTR data
, BSTR origin
,
2254 BSTR last_event_id
, IHTMLWindow2
*source
)
2256 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2257 FIXME("(%p)->(%s %x %x %s %s %s %p)\n", This
, debugstr_w(type
), can_bubble
, cancelable
,
2258 debugstr_w(data
), debugstr_w(origin
), debugstr_w(last_event_id
), source
);
2262 static const IDOMMessageEventVtbl DOMMessageEventVtbl
= {
2263 DOMMessageEvent_QueryInterface
,
2264 DOMMessageEvent_AddRef
,
2265 DOMMessageEvent_Release
,
2266 DOMMessageEvent_GetTypeInfoCount
,
2267 DOMMessageEvent_GetTypeInfo
,
2268 DOMMessageEvent_GetIDsOfNames
,
2269 DOMMessageEvent_Invoke
,
2270 DOMMessageEvent_get_data
,
2271 DOMMessageEvent_get_origin
,
2272 DOMMessageEvent_get_source
,
2273 DOMMessageEvent_initMessageEvent
2276 static DOMMessageEvent
*DOMMessageEvent_from_DOMEvent(DOMEvent
*event
)
2278 return CONTAINING_RECORD(event
, DOMMessageEvent
, event
);
2281 static void *DOMMessageEvent_query_interface(DOMEvent
*event
, REFIID riid
)
2283 DOMMessageEvent
*message_event
= DOMMessageEvent_from_DOMEvent(event
);
2284 if(IsEqualGUID(&IID_IDOMMessageEvent
, riid
))
2285 return &message_event
->IDOMMessageEvent_iface
;
2289 static void DOMMessageEvent_destroy(DOMEvent
*event
)
2291 DOMMessageEvent
*message_event
= DOMMessageEvent_from_DOMEvent(event
);
2292 heap_free(message_event
->data
);
2297 IDOMProgressEvent IDOMProgressEvent_iface
;
2300 static inline DOMProgressEvent
*impl_from_IDOMProgressEvent(IDOMProgressEvent
*iface
)
2302 return CONTAINING_RECORD(iface
, DOMProgressEvent
, IDOMProgressEvent_iface
);
2305 static HRESULT WINAPI
DOMProgressEvent_QueryInterface(IDOMProgressEvent
*iface
, REFIID riid
, void **ppv
)
2307 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2308 return IDOMEvent_QueryInterface(&This
->event
.IDOMEvent_iface
, riid
, ppv
);
2311 static ULONG WINAPI
DOMProgressEvent_AddRef(IDOMProgressEvent
*iface
)
2313 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2314 return IDOMEvent_AddRef(&This
->event
.IDOMEvent_iface
);
2317 static ULONG WINAPI
DOMProgressEvent_Release(IDOMProgressEvent
*iface
)
2319 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2320 return IDOMEvent_Release(&This
->event
.IDOMEvent_iface
);
2323 static HRESULT WINAPI
DOMProgressEvent_GetTypeInfoCount(IDOMProgressEvent
*iface
, UINT
*pctinfo
)
2325 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2326 return IDispatchEx_GetTypeInfoCount(&This
->event
.dispex
.IDispatchEx_iface
, pctinfo
);
2329 static HRESULT WINAPI
DOMProgressEvent_GetTypeInfo(IDOMProgressEvent
*iface
, UINT iTInfo
,
2330 LCID lcid
, ITypeInfo
**ppTInfo
)
2332 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2333 return IDispatchEx_GetTypeInfo(&This
->event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
2336 static HRESULT WINAPI
DOMProgressEvent_GetIDsOfNames(IDOMProgressEvent
*iface
, REFIID riid
,
2337 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2339 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2340 return IDispatchEx_GetIDsOfNames(&This
->event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
2344 static HRESULT WINAPI
DOMProgressEvent_Invoke(IDOMProgressEvent
*iface
, DISPID dispIdMember
,
2345 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2346 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2348 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2349 return IDispatchEx_Invoke(&This
->event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
2350 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2353 static HRESULT WINAPI
DOMProgressEvent_get_lengthComputable(IDOMProgressEvent
*iface
, VARIANT_BOOL
*p
)
2355 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2356 FIXME("(%p)->(%p)\n", This
, p
);
2360 static HRESULT WINAPI
DOMProgressEvent_get_loaded(IDOMProgressEvent
*iface
, ULONGLONG
*p
)
2362 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2363 FIXME("(%p)->(%p)\n", This
, p
);
2367 static HRESULT WINAPI
DOMProgressEvent_get_total(IDOMProgressEvent
*iface
, ULONGLONG
*p
)
2369 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2370 FIXME("(%p)->(%p)\n", This
, p
);
2374 static HRESULT WINAPI
DOMProgressEvent_initProgressEvent(IDOMProgressEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
2375 VARIANT_BOOL cancelable
, VARIANT_BOOL lengthComputable
,
2376 ULONGLONG loaded
, ULONGLONG total
)
2378 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2379 FIXME("(%p)->(%s %x %x %x %s %s)\n", This
, debugstr_w(type
), can_bubble
, cancelable
, lengthComputable
,
2380 wine_dbgstr_longlong(loaded
), wine_dbgstr_longlong(total
));
2384 static const IDOMProgressEventVtbl DOMProgressEventVtbl
= {
2385 DOMProgressEvent_QueryInterface
,
2386 DOMProgressEvent_AddRef
,
2387 DOMProgressEvent_Release
,
2388 DOMProgressEvent_GetTypeInfoCount
,
2389 DOMProgressEvent_GetTypeInfo
,
2390 DOMProgressEvent_GetIDsOfNames
,
2391 DOMProgressEvent_Invoke
,
2392 DOMProgressEvent_get_lengthComputable
,
2393 DOMProgressEvent_get_loaded
,
2394 DOMProgressEvent_get_total
,
2395 DOMProgressEvent_initProgressEvent
2398 static DOMProgressEvent
*DOMProgressEvent_from_DOMEvent(DOMEvent
*event
)
2400 return CONTAINING_RECORD(event
, DOMProgressEvent
, event
);
2403 static void *DOMProgressEvent_query_interface(DOMEvent
*event
, REFIID riid
)
2405 DOMProgressEvent
*This
= DOMProgressEvent_from_DOMEvent(event
);
2406 if(IsEqualGUID(&IID_IDOMProgressEvent
, riid
))
2407 return &This
->IDOMProgressEvent_iface
;
2411 static const tid_t DOMEvent_iface_tids
[] = {
2416 static dispex_static_data_t DOMEvent_dispex
= {
2423 static const tid_t DOMUIEvent_iface_tids
[] = {
2429 static dispex_static_data_t DOMUIEvent_dispex
= {
2433 DOMUIEvent_iface_tids
2436 static const tid_t DOMMouseEvent_iface_tids
[] = {
2443 static dispex_static_data_t DOMMouseEvent_dispex
= {
2446 DispDOMMouseEvent_tid
,
2447 DOMMouseEvent_iface_tids
2450 static const tid_t DOMKeyboardEvent_iface_tids
[] = {
2453 IDOMKeyboardEvent_tid
,
2457 static dispex_static_data_t DOMKeyboardEvent_dispex
= {
2460 DispDOMKeyboardEvent_tid
,
2461 DOMKeyboardEvent_iface_tids
2464 static const tid_t DOMCustomEvent_iface_tids
[] = {
2466 IDOMCustomEvent_tid
,
2470 static dispex_static_data_t DOMCustomEvent_dispex
= {
2473 DispDOMCustomEvent_tid
,
2474 DOMCustomEvent_iface_tids
2477 static const tid_t DOMMessageEvent_iface_tids
[] = {
2479 IDOMMessageEvent_tid
,
2483 dispex_static_data_t DOMMessageEvent_dispex
= {
2486 DispDOMMessageEvent_tid
,
2487 DOMMessageEvent_iface_tids
2490 static const tid_t DOMProgressEvent_iface_tids
[] = {
2492 IDOMProgressEvent_tid
,
2496 dispex_static_data_t DOMProgressEvent_dispex
= {
2499 DispDOMProgressEvent_tid
,
2500 DOMProgressEvent_iface_tids
2503 static BOOL
check_event_iface(nsIDOMEvent
*event
, REFIID riid
)
2508 nsres
= nsIDOMEvent_QueryInterface(event
, riid
, (void**)&iface
);
2509 if(NS_FAILED(nsres
))
2512 nsISupports_Release(iface
);
2516 static DOMEvent
*alloc_event(nsIDOMEvent
*nsevent
, compat_mode_t compat_mode
, eventid_t event_id
)
2518 dispex_static_data_t
*dispex_data
= &DOMEvent_dispex
;
2519 DOMEvent
*event
= NULL
;
2522 if(check_event_iface(nsevent
, &IID_nsIDOMCustomEvent
)) {
2523 DOMCustomEvent
*custom_event
= heap_alloc_zero(sizeof(*custom_event
));
2527 custom_event
->IDOMCustomEvent_iface
.lpVtbl
= &DOMCustomEventVtbl
;
2528 custom_event
->event
.query_interface
= DOMCustomEvent_query_interface
;
2529 custom_event
->event
.destroy
= DOMCustomEvent_destroy
;
2530 event
= &custom_event
->event
;
2531 dispex_data
= &DOMCustomEvent_dispex
;
2532 }else if(event_id
== EVENTID_MESSAGE
) {
2533 DOMMessageEvent
*message_event
= heap_alloc_zero(sizeof(*message_event
));
2537 message_event
->IDOMMessageEvent_iface
.lpVtbl
= &DOMMessageEventVtbl
;
2538 message_event
->event
.query_interface
= DOMMessageEvent_query_interface
;
2539 message_event
->event
.destroy
= DOMMessageEvent_destroy
;
2540 event
= &message_event
->event
;
2541 dispex_data
= &DOMMessageEvent_dispex
;
2542 }else if(event_info
[event_id
].type
== EVENT_TYPE_PROGRESS
&& compat_mode
>= COMPAT_MODE_IE10
) {
2543 DOMProgressEvent
*progress_event
= heap_alloc_zero(sizeof(*progress_event
));
2547 progress_event
->IDOMProgressEvent_iface
.lpVtbl
= &DOMProgressEventVtbl
;
2548 progress_event
->event
.query_interface
= DOMProgressEvent_query_interface
;
2549 event
= &progress_event
->event
;
2550 dispex_data
= &DOMProgressEvent_dispex
;
2552 event
= heap_alloc_zero(sizeof(*event
));
2557 event
->IDOMEvent_iface
.lpVtbl
= &DOMEventVtbl
;
2558 event
->IDOMUIEvent_iface
.lpVtbl
= &DOMUIEventVtbl
;
2559 event
->IDOMMouseEvent_iface
.lpVtbl
= &DOMMouseEventVtbl
;
2560 event
->IDOMKeyboardEvent_iface
.lpVtbl
= &DOMKeyboardEventVtbl
;
2562 event
->event_id
= event_id
;
2563 if(event_id
!= EVENTID_LAST
) {
2564 event
->type
= heap_strdupW(event_info
[event_id
].name
);
2569 event
->bubbles
= (event_info
[event_id
].flags
& EVENT_BUBBLES
) != 0;
2570 event
->cancelable
= (event_info
[event_id
].flags
& EVENT_CANCELABLE
) != 0;
2572 nsIDOMEvent_AddRef(event
->nsevent
= nsevent
);
2574 event
->time_stamp
= get_time_stamp();
2576 nsres
= nsIDOMEvent_QueryInterface(nsevent
, &IID_nsIDOMUIEvent
, (void**)&event
->ui_event
);
2577 if(NS_SUCCEEDED(nsres
))
2578 dispex_data
= &DOMUIEvent_dispex
;
2580 event
->ui_event
= NULL
;
2582 nsres
= nsIDOMEvent_QueryInterface(nsevent
, &IID_nsIDOMMouseEvent
, (void**)&event
->mouse_event
);
2583 if(NS_SUCCEEDED(nsres
))
2584 dispex_data
= &DOMMouseEvent_dispex
;
2586 event
->mouse_event
= NULL
;
2588 nsres
= nsIDOMEvent_QueryInterface(nsevent
, &IID_nsIDOMKeyEvent
, (void**)&event
->keyboard_event
);
2589 if(NS_SUCCEEDED(nsres
))
2590 dispex_data
= &DOMKeyboardEvent_dispex
;
2592 event
->keyboard_event
= NULL
;
2594 init_dispatch(&event
->dispex
, (IUnknown
*)&event
->IDOMEvent_iface
, dispex_data
, compat_mode
);
2598 HRESULT
create_event_from_nsevent(nsIDOMEvent
*nsevent
, compat_mode_t compat_mode
, DOMEvent
**ret_event
)
2600 eventid_t event_id
= EVENTID_LAST
;
2605 nsAString_Init(&nsstr
, NULL
);
2606 nsres
= nsIDOMEvent_GetType(nsevent
, &nsstr
);
2607 if(NS_SUCCEEDED(nsres
)) {
2609 nsAString_GetData(&nsstr
, &type
);
2610 event_id
= str_to_eid(type
);
2611 if(event_id
== EVENTID_LAST
)
2612 FIXME("unknown event type %s\n", debugstr_w(type
));
2614 ERR("GetType failed: %08lx\n", nsres
);
2616 nsAString_Finish(&nsstr
);
2618 event
= alloc_event(nsevent
, compat_mode
, event_id
);
2620 return E_OUTOFMEMORY
;
2622 event
->trusted
= TRUE
;
2627 HRESULT
create_document_event_str(HTMLDocumentNode
*doc
, const WCHAR
*type
, IDOMEvent
**ret_event
)
2629 nsIDOMEvent
*nsevent
;
2634 nsAString_InitDepend(&nsstr
, type
);
2635 nsres
= nsIDOMHTMLDocument_CreateEvent(doc
->nsdoc
, &nsstr
, &nsevent
);
2636 nsAString_Finish(&nsstr
);
2637 if(NS_FAILED(nsres
)) {
2638 FIXME("CreateEvent(%s) failed: %08lx\n", debugstr_w(type
), nsres
);
2642 event
= alloc_event(nsevent
, dispex_compat_mode(&doc
->node
.event_target
.dispex
), EVENTID_LAST
);
2643 nsIDOMEvent_Release(nsevent
);
2645 return E_OUTOFMEMORY
;
2647 *ret_event
= &event
->IDOMEvent_iface
;
2651 HRESULT
create_document_event(HTMLDocumentNode
*doc
, eventid_t event_id
, DOMEvent
**ret_event
)
2653 nsIDOMEvent
*nsevent
;
2658 nsAString_InitDepend(&nsstr
, event_types
[event_info
[event_id
].type
]);
2659 nsres
= nsIDOMHTMLDocument_CreateEvent(doc
->nsdoc
, &nsstr
, &nsevent
);
2660 nsAString_Finish(&nsstr
);
2661 if(NS_FAILED(nsres
)) {
2662 FIXME("CreateEvent(%s) failed: %08lx\n", debugstr_w(event_types
[event_info
[event_id
].type
]), nsres
);
2666 event
= alloc_event(nsevent
, doc
->document_mode
, event_id
);
2668 return E_OUTOFMEMORY
;
2670 event
->event_id
= event_id
;
2671 event
->trusted
= TRUE
;
2676 HRESULT
create_message_event(HTMLDocumentNode
*doc
, BSTR data
, DOMEvent
**ret
)
2678 DOMMessageEvent
*message_event
;
2682 hres
= create_document_event(doc
, EVENTID_MESSAGE
, &event
);
2685 message_event
= DOMMessageEvent_from_DOMEvent(event
);
2687 if(!(message_event
->data
= heap_strdupW(data
))) {
2688 IDOMEvent_Release(&event
->IDOMEvent_iface
);
2689 return E_OUTOFMEMORY
;
2696 static HRESULT
call_disp_func(IDispatch
*disp
, DISPPARAMS
*dp
, VARIANT
*retv
)
2698 IDispatchEx
*dispex
;
2702 memset(&ei
, 0, sizeof(ei
));
2704 hres
= IDispatch_QueryInterface(disp
, &IID_IDispatchEx
, (void**)&dispex
);
2705 if(SUCCEEDED(hres
)) {
2706 hres
= IDispatchEx_InvokeEx(dispex
, 0, GetUserDefaultLCID(), DISPATCH_METHOD
, dp
, retv
, &ei
, NULL
);
2707 IDispatchEx_Release(dispex
);
2709 TRACE("Could not get IDispatchEx interface: %08lx\n", hres
);
2710 hres
= IDispatch_Invoke(disp
, 0, &IID_NULL
, GetUserDefaultLCID(), DISPATCH_METHOD
,
2711 dp
, retv
, &ei
, NULL
);
2717 static HRESULT
call_cp_func(IDispatch
*disp
, DISPID dispid
, IHTMLEventObj
*event_obj
, VARIANT
*retv
)
2719 DISPPARAMS dp
= {NULL
,NULL
,0,0};
2724 TRACE("%p,%ld,%p,%p\n", disp
, dispid
, event_obj
, retv
);
2727 V_VT(&event_arg
) = VT_DISPATCH
;
2728 V_DISPATCH(&event_arg
) = (IDispatch
*)event_obj
;
2729 dp
.rgvarg
= &event_arg
;
2733 memset(&ei
, 0, sizeof(ei
));
2734 return IDispatch_Invoke(disp
, dispid
, &IID_NULL
, 0, DISPATCH_METHOD
, &dp
, retv
, &ei
, &argerr
);
2737 static BOOL
use_event_quirks(EventTarget
*event_target
)
2739 return dispex_compat_mode(&event_target
->dispex
) < COMPAT_MODE_IE9
;
2742 static BOOL
is_cp_event(cp_static_data_t
*data
, DISPID dispid
)
2747 if(!data
|| dispid
== DISPID_UNKNOWN
)
2751 hres
= get_dispids(data
->tid
, &data
->id_cnt
, &data
->ids
);
2757 max
= data
->id_cnt
-1;
2760 if(data
->ids
[i
] == dispid
)
2763 if(data
->ids
[i
] < dispid
)
2772 static void call_event_handlers(EventTarget
*event_target
, DOMEvent
*event
, dispatch_mode_t dispatch_mode
)
2774 const listener_container_t
*container
= get_listener_container(event_target
, event
->type
, FALSE
);
2775 event_listener_t
*listener
, listeners_buf
[8], *listeners
= listeners_buf
;
2776 unsigned listeners_cnt
, listeners_size
;
2777 ConnectionPointContainer
*cp_container
= NULL
;
2778 const event_target_vtbl_t
*vtbl
= NULL
;
2779 BOOL skip_onevent_listener
= FALSE
;
2783 assert(!event
->current_target
);
2784 event
->current_target
= event_target
;
2786 if(container
&& !list_empty(&container
->listeners
) && event
->phase
!= DEP_CAPTURING_PHASE
) {
2787 listener
= LIST_ENTRY(list_tail(&container
->listeners
), event_listener_t
, entry
);
2788 if(listener
&& listener
->function
&& listener
->type
== LISTENER_TYPE_ONEVENT
2789 && use_event_quirks(event_target
)) {
2790 DISPID named_arg
= DISPID_THIS
;
2792 DISPPARAMS dp
= {&arg
, &named_arg
, 1, 1};
2794 skip_onevent_listener
= TRUE
;
2796 V_VT(&arg
) = VT_DISPATCH
;
2797 V_DISPATCH(&arg
) = (IDispatch
*)&event_target
->dispex
.IDispatchEx_iface
;
2798 V_VT(&v
) = VT_EMPTY
;
2800 TRACE("%p %s >>>\n", event_target
, debugstr_w(event
->type
));
2801 hres
= call_disp_func(listener
->function
, &dp
, &v
);
2803 TRACE("%p %s <<< %s\n", event_target
, debugstr_w(event
->type
), debugstr_variant(&v
));
2805 if(event
->cancelable
) {
2806 if(V_VT(&v
) == VT_BOOL
) {
2808 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
2809 }else if(V_VT(&v
) != VT_EMPTY
) {
2810 FIXME("unhandled result %s\n", debugstr_variant(&v
));
2815 WARN("%p %s <<< %08lx\n", event_target
, debugstr_w(event
->type
), hres
);
2821 listeners_size
= ARRAY_SIZE(listeners_buf
);
2824 LIST_FOR_EACH_ENTRY(listener
, &container
->listeners
, event_listener_t
, entry
) {
2825 if(!listener
->function
)
2827 switch(listener
->type
) {
2828 case LISTENER_TYPE_ONEVENT
:
2829 if(skip_onevent_listener
|| event
->phase
== DEP_CAPTURING_PHASE
)
2832 case LISTENER_TYPE_CAPTURE
:
2833 if(event
->phase
== DEP_BUBBLING_PHASE
|| dispatch_mode
== DISPATCH_LEGACY
)
2836 case LISTENER_TYPE_BUBBLE
:
2837 if(event
->phase
== DEP_CAPTURING_PHASE
|| dispatch_mode
== DISPATCH_LEGACY
)
2840 case LISTENER_TYPE_ATTACHED
:
2841 if(event
->phase
== DEP_CAPTURING_PHASE
|| dispatch_mode
== DISPATCH_STANDARD
)
2846 if(listeners_cnt
== listeners_size
) {
2847 event_listener_t
*new_listeners
;
2848 if(listeners
== listeners_buf
) {
2849 new_listeners
= heap_alloc(listeners_size
* 2 * sizeof(*new_listeners
));
2852 memcpy(new_listeners
, listeners
, listeners_cnt
* sizeof(*listeners
));
2854 new_listeners
= heap_realloc(listeners
, listeners_size
* 2 * sizeof(*new_listeners
));
2856 listeners
= new_listeners
;
2857 listeners_size
*= 2;
2860 listeners
[listeners_cnt
].type
= listener
->type
;
2861 IDispatch_AddRef(listeners
[listeners_cnt
].function
= listener
->function
);
2866 for(listener
= listeners
; !event
->stop_immediate_propagation
2867 && listener
< listeners
+ listeners_cnt
; listener
++) {
2868 if(listener
->type
!= LISTENER_TYPE_ATTACHED
) {
2869 DISPID named_arg
= DISPID_THIS
;
2871 DISPPARAMS dp
= {args
, &named_arg
, 2, 1};
2873 V_VT(args
) = VT_DISPATCH
;
2874 V_DISPATCH(args
) = (IDispatch
*)&event_target
->dispex
.IDispatchEx_iface
;
2875 V_VT(args
+1) = VT_DISPATCH
;
2876 V_DISPATCH(args
+1) = dispatch_mode
== DISPATCH_LEGACY
2877 ? (IDispatch
*)event
->event_obj
: (IDispatch
*)&event
->IDOMEvent_iface
;
2878 V_VT(&v
) = VT_EMPTY
;
2880 TRACE("%p %s >>>\n", event_target
, debugstr_w(event
->type
));
2881 hres
= call_disp_func(listener
->function
, &dp
, &v
);
2883 TRACE("%p %s <<< %s\n", event_target
, debugstr_w(event
->type
),
2884 debugstr_variant(&v
));
2886 if(event
->cancelable
) {
2887 if(V_VT(&v
) == VT_BOOL
) {
2889 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
2890 }else if(V_VT(&v
) != VT_EMPTY
) {
2891 FIXME("unhandled result %s\n", debugstr_variant(&v
));
2896 WARN("%p %s <<< %08lx\n", event_target
, debugstr_w(event
->type
), hres
);
2900 DISPPARAMS dp
= {&arg
, NULL
, 1, 0};
2902 V_VT(&arg
) = VT_DISPATCH
;
2903 V_DISPATCH(&arg
) = (IDispatch
*)event
->event_obj
;
2904 V_VT(&v
) = VT_EMPTY
;
2906 TRACE("%p %s attached >>>\n", event_target
, debugstr_w(event
->type
));
2907 hres
= call_disp_func(listener
->function
, &dp
, &v
);
2909 TRACE("%p %s attached <<<\n", event_target
, debugstr_w(event
->type
));
2911 if(event
->cancelable
) {
2912 if(V_VT(&v
) == VT_BOOL
) {
2914 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
2915 }else if(V_VT(&v
) != VT_EMPTY
) {
2916 FIXME("unhandled result %s\n", debugstr_variant(&v
));
2921 WARN("%p %s attached <<< %08lx\n", event_target
, debugstr_w(event
->type
), hres
);
2926 for(listener
= listeners
; listener
< listeners
+ listeners_cnt
; listener
++)
2927 IDispatch_Release(listener
->function
);
2928 if(listeners
!= listeners_buf
)
2929 heap_free(listeners
);
2931 if(event
->phase
!= DEP_CAPTURING_PHASE
&& event
->event_id
!= EVENTID_LAST
2932 && event_info
[event
->event_id
].dispid
&& (vtbl
= dispex_get_vtbl(&event_target
->dispex
))
2933 && vtbl
->get_cp_container
)
2934 cp_container
= vtbl
->get_cp_container(&event_target
->dispex
);
2936 if(cp_container
->cps
) {
2937 ConnectionPoint
*cp
;
2940 for(j
=0; cp_container
->cp_entries
[j
].riid
; j
++) {
2941 cp
= cp_container
->cps
+ j
;
2942 if(!cp
->sinks_size
|| !is_cp_event(cp
->data
, event_info
[event
->event_id
].dispid
))
2945 for(i
=0; i
< cp
->sinks_size
; i
++) {
2946 if(!cp
->sinks
[i
].disp
)
2949 V_VT(&v
) = VT_EMPTY
;
2951 TRACE("%p cp %s [%u] >>>\n", event_target
, debugstr_w(event
->type
), i
);
2952 hres
= call_cp_func(cp
->sinks
[i
].disp
, event_info
[event
->event_id
].dispid
,
2953 cp
->data
->pass_event_arg
? event
->event_obj
: NULL
, &v
);
2955 TRACE("%p cp %s [%u] <<<\n", event_target
, debugstr_w(event
->type
), i
);
2957 if(event
->cancelable
) {
2958 if(V_VT(&v
) == VT_BOOL
) {
2960 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
2961 }else if(V_VT(&v
) != VT_EMPTY
) {
2962 FIXME("unhandled result %s\n", debugstr_variant(&v
));
2967 WARN("%p cp %s [%u] <<< %08lx\n", event_target
, debugstr_w(event
->type
), i
, hres
);
2972 IConnectionPointContainer_Release(&cp_container
->IConnectionPointContainer_iface
);
2975 event
->current_target
= NULL
;
2978 static HRESULT
dispatch_event_object(EventTarget
*event_target
, DOMEvent
*event
,
2979 dispatch_mode_t dispatch_mode
, VARIANT_BOOL
*r
)
2981 EventTarget
*target_chain_buf
[8], **target_chain
= target_chain_buf
;
2982 unsigned chain_cnt
, chain_buf_size
, i
;
2983 const event_target_vtbl_t
*vtbl
, *target_vtbl
;
2984 HTMLEventObj
*event_obj_ref
= NULL
;
2985 IHTMLEventObj
*prev_event
= NULL
;
2989 TRACE("(%p) %s\n", event_target
, debugstr_w(event
->type
));
2992 FIXME("Uninitialized event.\n");
2996 if(event
->current_target
) {
2997 FIXME("event is being dispatched.\n");
3001 iter
= event_target
;
3002 IEventTarget_AddRef(&event_target
->IEventTarget_iface
);
3005 chain_buf_size
= ARRAY_SIZE(target_chain_buf
);
3008 if(chain_cnt
== chain_buf_size
) {
3009 EventTarget
**new_chain
;
3010 if(target_chain
== target_chain_buf
) {
3011 new_chain
= heap_alloc(chain_buf_size
* 2 * sizeof(*new_chain
));
3014 memcpy(new_chain
, target_chain
, chain_buf_size
* sizeof(*new_chain
));
3016 new_chain
= heap_realloc(target_chain
, chain_buf_size
* 2 * sizeof(*new_chain
));
3020 chain_buf_size
*= 2;
3021 target_chain
= new_chain
;
3024 target_chain
[chain_cnt
++] = iter
;
3026 if(!(vtbl
= dispex_get_vtbl(&iter
->dispex
)) || !vtbl
->get_parent_event_target
)
3028 iter
= vtbl
->get_parent_event_target(&iter
->dispex
);
3031 if(!event
->event_obj
&& !event
->no_event_obj
) {
3032 event_obj_ref
= alloc_event_obj(event
, dispex_compat_mode(&event
->dispex
));
3034 event
->event_obj
= &event_obj_ref
->IHTMLEventObj_iface
;
3037 target_vtbl
= dispex_get_vtbl(&event_target
->dispex
);
3038 if(target_vtbl
&& target_vtbl
->set_current_event
)
3039 prev_event
= target_vtbl
->set_current_event(&event_target
->dispex
, event
->event_obj
);
3042 IEventTarget_Release(&event
->target
->IEventTarget_iface
);
3043 event
->target
= event_target
;
3044 IEventTarget_AddRef(&event_target
->IEventTarget_iface
);
3046 event
->phase
= DEP_CAPTURING_PHASE
;
3048 while(!event
->stop_propagation
&& i
)
3049 call_event_handlers(target_chain
[i
--], event
, dispatch_mode
);
3051 if(!event
->stop_propagation
) {
3052 event
->phase
= DEP_AT_TARGET
;
3053 call_event_handlers(target_chain
[0], event
, dispatch_mode
);
3056 if(event
->bubbles
) {
3057 event
->phase
= DEP_BUBBLING_PHASE
;
3058 for(i
= 1; !event
->stop_propagation
&& i
< chain_cnt
; i
++)
3059 call_event_handlers(target_chain
[i
], event
, dispatch_mode
);
3063 *r
= variant_bool(!event
->prevent_default
);
3065 if(target_vtbl
&& target_vtbl
->set_current_event
) {
3066 prev_event
= target_vtbl
->set_current_event(&event_target
->dispex
, prev_event
);
3068 IHTMLEventObj_Release(prev_event
);
3071 if(event
->event_id
!= EVENTID_LAST
&& (event_info
[event
->event_id
].flags
& EVENT_HASDEFAULTHANDLERS
)) {
3072 BOOL prevent_default
= event
->prevent_default
;
3073 for(i
= 0; !prevent_default
&& i
< chain_cnt
; i
++) {
3074 vtbl
= dispex_get_vtbl(&target_chain
[i
]->dispex
);
3075 if(!vtbl
|| !vtbl
->handle_event_default
)
3077 hres
= vtbl
->handle_event_default(&event_target
->dispex
, event
->event_id
,
3078 event
->nsevent
, &prevent_default
);
3079 if(FAILED(hres
) || event
->stop_propagation
)
3082 nsIDOMEvent_PreventDefault(event
->nsevent
);
3086 event
->prevent_default
= FALSE
;
3088 event
->event_obj
= NULL
;
3089 IHTMLEventObj_Release(&event_obj_ref
->IHTMLEventObj_iface
);
3092 for(i
= 0; i
< chain_cnt
; i
++)
3093 IEventTarget_Release(&target_chain
[i
]->IEventTarget_iface
);
3094 if(target_chain
!= target_chain_buf
)
3095 heap_free(target_chain
);
3100 void dispatch_event(EventTarget
*event_target
, DOMEvent
*event
)
3102 dispatch_event_object(event_target
, event
, DISPATCH_BOTH
, NULL
);
3105 * We may have registered multiple Gecko listeners for the same event type,
3106 * but we already dispatched event to all relevant targets. Stop event
3107 * propagation here to avoid events being dispatched multiple times.
3109 if(event
->event_id
!= EVENTID_LAST
&& (event_info
[event
->event_id
].flags
& EVENT_BIND_TO_TARGET
))
3110 nsIDOMEvent_StopPropagation(event
->nsevent
);
3113 HRESULT
fire_event(HTMLDOMNode
*node
, const WCHAR
*event_name
, VARIANT
*event_var
, VARIANT_BOOL
*cancelled
)
3115 HTMLEventObj
*event_obj
= NULL
;
3117 HRESULT hres
= S_OK
;
3119 eid
= attr_to_eid(event_name
);
3120 if(eid
== EVENTID_LAST
) {
3121 WARN("unknown event %s\n", debugstr_w(event_name
));
3122 return E_INVALIDARG
;
3125 if(event_var
&& V_VT(event_var
) != VT_EMPTY
&& V_VT(event_var
) != VT_ERROR
) {
3126 if(V_VT(event_var
) != VT_DISPATCH
) {
3127 FIXME("event_var %s not supported\n", debugstr_variant(event_var
));
3131 if(V_DISPATCH(event_var
)) {
3132 IHTMLEventObj
*event_iface
;
3134 hres
= IDispatch_QueryInterface(V_DISPATCH(event_var
), &IID_IHTMLEventObj
, (void**)&event_iface
);
3136 FIXME("No IHTMLEventObj iface\n");
3140 event_obj
= unsafe_impl_from_IHTMLEventObj(event_iface
);
3142 ERR("Not our IHTMLEventObj?\n");
3143 IHTMLEventObj_Release(event_iface
);
3150 event_obj
= alloc_event_obj(NULL
, dispex_compat_mode(&node
->event_target
.dispex
));
3152 return E_OUTOFMEMORY
;
3155 if(!event_obj
->event
)
3156 hres
= create_document_event(node
->doc
, eid
, &event_obj
->event
);
3158 if(SUCCEEDED(hres
)) {
3159 event_obj
->event
->event_obj
= &event_obj
->IHTMLEventObj_iface
;
3160 dispatch_event_object(&node
->event_target
, event_obj
->event
, DISPATCH_LEGACY
, NULL
);
3161 event_obj
->event
->event_obj
= NULL
;
3164 IHTMLEventObj_Release(&event_obj
->IHTMLEventObj_iface
);
3168 *cancelled
= VARIANT_TRUE
; /* FIXME */
3172 HRESULT
ensure_doc_nsevent_handler(HTMLDocumentNode
*doc
, nsIDOMNode
*nsnode
, eventid_t eid
)
3174 TRACE("%s\n", debugstr_w(event_info
[eid
].name
));
3180 case EVENTID_FOCUSIN
:
3181 doc
->event_vector
[eid
] = TRUE
;
3182 eid
= EVENTID_FOCUS
;
3184 case EVENTID_FOCUSOUT
:
3185 doc
->event_vector
[eid
] = TRUE
;
3194 if(event_info
[eid
].flags
& EVENT_DEFAULTLISTENER
) {
3196 }else if(event_info
[eid
].flags
& EVENT_BIND_TO_TARGET
) {
3198 nsnode
= doc
->node
.nsnode
;
3203 if(!nsnode
|| nsnode
== doc
->node
.nsnode
) {
3204 if(doc
->event_vector
[eid
])
3206 doc
->event_vector
[eid
] = TRUE
;
3209 add_nsevent_listener(doc
, nsnode
, event_info
[eid
].name
);
3213 void detach_events(HTMLDocumentNode
*doc
)
3215 if(doc
->event_vector
) {
3218 for(i
=0; i
< EVENTID_LAST
; i
++) {
3219 if(doc
->event_vector
[i
]) {
3220 detach_nsevent(doc
, event_info
[i
].name
);
3221 doc
->event_vector
[i
] = FALSE
;
3226 release_nsevents(doc
);
3229 static HRESULT
get_event_dispex_ref(EventTarget
*event_target
, eventid_t eid
, BOOL alloc
, VARIANT
**ret
)
3234 lstrcpyW(buf
+2, event_info
[eid
].name
);
3235 return dispex_get_dprop_ref(&event_target
->dispex
, buf
, alloc
, ret
);
3238 static event_listener_t
*get_onevent_listener(EventTarget
*event_target
, eventid_t eid
, BOOL alloc
)
3240 listener_container_t
*container
;
3241 event_listener_t
*listener
;
3243 container
= get_listener_container(event_target
, event_info
[eid
].name
, alloc
);
3247 LIST_FOR_EACH_ENTRY_REV(listener
, &container
->listeners
, event_listener_t
, entry
) {
3248 if(listener
->type
== LISTENER_TYPE_ONEVENT
)
3255 listener
= heap_alloc(sizeof(*listener
));
3259 listener
->type
= LISTENER_TYPE_ONEVENT
;
3260 listener
->function
= NULL
;
3261 list_add_tail(&container
->listeners
, &listener
->entry
);
3265 static void remove_event_handler(EventTarget
*event_target
, eventid_t eid
)
3267 event_listener_t
*listener
;
3271 hres
= get_event_dispex_ref(event_target
, eid
, FALSE
, &store
);
3273 VariantClear(store
);
3275 listener
= get_onevent_listener(event_target
, eid
, FALSE
);
3276 if(listener
&& listener
->function
) {
3277 IDispatch_Release(listener
->function
);
3278 listener
->function
= NULL
;
3282 static HRESULT
set_event_handler_disp(EventTarget
*event_target
, eventid_t eid
, IDispatch
*disp
)
3284 event_listener_t
*listener
;
3286 if(event_info
[eid
].flags
& EVENT_FIXME
)
3287 FIXME("unimplemented event %s\n", debugstr_w(event_info
[eid
].name
));
3289 remove_event_handler(event_target
, eid
);
3293 listener
= get_onevent_listener(event_target
, eid
, TRUE
);
3295 return E_OUTOFMEMORY
;
3297 if(listener
->function
)
3298 IDispatch_Release(listener
->function
);
3300 IDispatch_AddRef(listener
->function
= disp
);
3304 HRESULT
set_event_handler(EventTarget
*event_target
, eventid_t eid
, VARIANT
*var
)
3308 if(use_event_quirks(event_target
)) {
3309 WARN("attempt to set to VT_EMPTY in quirks mode\n");
3314 remove_event_handler(event_target
, eid
);
3318 return set_event_handler_disp(event_target
, eid
, V_DISPATCH(var
));
3324 if(!use_event_quirks(event_target
))
3325 FIXME("Setting to string %s not supported\n", debugstr_w(V_BSTR(var
)));
3328 * Setting event handler to string is a rare case and we don't want to
3329 * complicate nor increase memory of listener_container_t for that. Instead,
3330 * we store the value in DispatchEx, which can already handle custom
3333 remove_event_handler(event_target
, eid
);
3335 hres
= get_event_dispex_ref(event_target
, eid
, TRUE
, &v
);
3339 V_BSTR(v
) = SysAllocString(V_BSTR(var
));
3341 return E_OUTOFMEMORY
;
3347 FIXME("not handler %s\n", debugstr_variant(var
));
3354 HRESULT
get_event_handler(EventTarget
*event_target
, eventid_t eid
, VARIANT
*var
)
3356 event_listener_t
*listener
;
3360 hres
= get_event_dispex_ref(event_target
, eid
, FALSE
, &v
);
3361 if(SUCCEEDED(hres
) && V_VT(v
) != VT_EMPTY
) {
3362 V_VT(var
) = VT_EMPTY
;
3363 return VariantCopy(var
, v
);
3366 listener
= get_onevent_listener(event_target
, eid
, FALSE
);
3367 if(listener
&& listener
->function
) {
3368 V_VT(var
) = VT_DISPATCH
;
3369 V_DISPATCH(var
) = listener
->function
;
3370 IDispatch_AddRef(V_DISPATCH(var
));
3372 V_VT(var
) = VT_NULL
;
3378 HRESULT
attach_event(EventTarget
*event_target
, BSTR name
, IDispatch
*disp
, VARIANT_BOOL
*res
)
3380 listener_container_t
*container
;
3381 event_listener_t
*listener
;
3384 eid
= attr_to_eid(name
);
3385 if(eid
== EVENTID_LAST
) {
3386 WARN("Unknown event\n");
3387 *res
= VARIANT_TRUE
;
3391 container
= get_listener_container(event_target
, event_info
[eid
].name
, TRUE
);
3393 return E_OUTOFMEMORY
;
3395 listener
= heap_alloc(sizeof(*listener
));
3397 return E_OUTOFMEMORY
;
3399 listener
->type
= LISTENER_TYPE_ATTACHED
;
3400 IDispatch_AddRef(listener
->function
= disp
);
3401 if(use_event_quirks(event_target
))
3402 list_add_head(&container
->listeners
, &listener
->entry
);
3404 list_add_tail(&container
->listeners
, &listener
->entry
);
3406 *res
= VARIANT_TRUE
;
3410 HRESULT
detach_event(EventTarget
*event_target
, BSTR name
, IDispatch
*disp
)
3414 eid
= attr_to_eid(name
);
3415 if(eid
== EVENTID_LAST
) {
3416 WARN("Unknown event\n");
3420 remove_event_listener(event_target
, event_info
[eid
].name
, LISTENER_TYPE_ATTACHED
, disp
);
3424 void bind_target_event(HTMLDocumentNode
*doc
, EventTarget
*event_target
, const WCHAR
*event
, IDispatch
*disp
)
3428 TRACE("(%p %p %s %p)\n", doc
, event_target
, debugstr_w(event
), disp
);
3430 eid
= attr_to_eid(event
);
3431 if(eid
== EVENTID_LAST
) {
3432 WARN("Unsupported event %s\n", debugstr_w(event
));
3436 set_event_handler_disp(event_target
, eid
, disp
);
3439 void update_doc_cp_events(HTMLDocumentNode
*doc
, cp_static_data_t
*cp
)
3443 for(i
=0; i
< EVENTID_LAST
; i
++) {
3444 if((event_info
[i
].flags
& EVENT_DEFAULTLISTENER
) && is_cp_event(cp
, event_info
[i
].dispid
))
3445 ensure_doc_nsevent_handler(doc
, NULL
, i
);
3449 void check_event_attr(HTMLDocumentNode
*doc
, nsIDOMElement
*nselem
)
3451 nsIDOMMozNamedAttrMap
*attr_map
;
3452 const PRUnichar
*name
, *value
;
3453 nsAString name_str
, value_str
;
3454 HTMLDOMNode
*node
= NULL
;
3463 nsres
= nsIDOMElement_HasAttributes(nselem
, &has_attrs
);
3464 if(NS_FAILED(nsres
) || !has_attrs
)
3467 nsres
= nsIDOMElement_GetAttributes(nselem
, &attr_map
);
3468 if(NS_FAILED(nsres
))
3471 nsres
= nsIDOMMozNamedAttrMap_GetLength(attr_map
, &length
);
3472 assert(nsres
== NS_OK
);
3474 nsAString_Init(&name_str
, NULL
);
3475 nsAString_Init(&value_str
, NULL
);
3477 for(i
= 0; i
< length
; i
++) {
3478 nsres
= nsIDOMMozNamedAttrMap_Item(attr_map
, i
, &attr
);
3479 if(NS_FAILED(nsres
))
3482 nsres
= nsIDOMAttr_GetName(attr
, &name_str
);
3483 if(NS_FAILED(nsres
)) {
3484 nsIDOMAttr_Release(attr
);
3488 nsAString_GetData(&name_str
, &name
);
3489 eid
= attr_to_eid(name
);
3490 if(eid
== EVENTID_LAST
) {
3491 nsIDOMAttr_Release(attr
);
3495 nsres
= nsIDOMAttr_GetValue(attr
, &value_str
);
3496 nsIDOMAttr_Release(attr
);
3497 if(NS_FAILED(nsres
))
3500 nsAString_GetData(&value_str
, &value
);
3504 TRACE("%p.%s = %s\n", nselem
, debugstr_w(name
), debugstr_w(value
));
3506 disp
= script_parse_event(doc
->window
, value
);
3511 hres
= get_node((nsIDOMNode
*)nselem
, TRUE
, &node
);
3513 IDispatch_Release(disp
);
3518 set_event_handler_disp(get_node_event_prop_target(node
, eid
), eid
, disp
);
3519 IDispatch_Release(disp
);
3524 nsAString_Finish(&name_str
);
3525 nsAString_Finish(&value_str
);
3526 nsIDOMMozNamedAttrMap_Release(attr_map
);
3529 HRESULT
doc_init_events(HTMLDocumentNode
*doc
)
3534 doc
->event_vector
= heap_alloc_zero(EVENTID_LAST
*sizeof(BOOL
));
3535 if(!doc
->event_vector
)
3536 return E_OUTOFMEMORY
;
3540 for(i
=0; i
< EVENTID_LAST
; i
++) {
3541 if(event_info
[i
].flags
& EVENT_HASDEFAULTHANDLERS
) {
3542 hres
= ensure_doc_nsevent_handler(doc
, NULL
, i
);
3551 static inline EventTarget
*impl_from_IEventTarget(IEventTarget
*iface
)
3553 return CONTAINING_RECORD(iface
, EventTarget
, IEventTarget_iface
);
3556 static HRESULT WINAPI
EventTarget_QueryInterface(IEventTarget
*iface
, REFIID riid
, void **ppv
)
3558 EventTarget
*This
= impl_from_IEventTarget(iface
);
3559 return IDispatchEx_QueryInterface(&This
->dispex
.IDispatchEx_iface
, riid
, ppv
);
3562 static ULONG WINAPI
EventTarget_AddRef(IEventTarget
*iface
)
3564 EventTarget
*This
= impl_from_IEventTarget(iface
);
3565 return IDispatchEx_AddRef(&This
->dispex
.IDispatchEx_iface
);
3568 static ULONG WINAPI
EventTarget_Release(IEventTarget
*iface
)
3570 EventTarget
*This
= impl_from_IEventTarget(iface
);
3571 return IDispatchEx_Release(&This
->dispex
.IDispatchEx_iface
);
3574 static HRESULT WINAPI
EventTarget_GetTypeInfoCount(IEventTarget
*iface
, UINT
*pctinfo
)
3576 EventTarget
*This
= impl_from_IEventTarget(iface
);
3577 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
3580 static HRESULT WINAPI
EventTarget_GetTypeInfo(IEventTarget
*iface
, UINT iTInfo
,
3581 LCID lcid
, ITypeInfo
**ppTInfo
)
3583 EventTarget
*This
= impl_from_IEventTarget(iface
);
3584 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
3587 static HRESULT WINAPI
EventTarget_GetIDsOfNames(IEventTarget
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
3588 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
3590 EventTarget
*This
= impl_from_IEventTarget(iface
);
3591 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
,
3592 rgszNames
, cNames
, lcid
, rgDispId
);
3595 static HRESULT WINAPI
EventTarget_Invoke(IEventTarget
*iface
, DISPID dispIdMember
,
3596 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
3597 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
3599 EventTarget
*This
= impl_from_IEventTarget(iface
);
3600 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
,
3601 riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
3604 static HRESULT WINAPI
EventTarget_addEventListener(IEventTarget
*iface
, BSTR type
,
3605 IDispatch
*function
, VARIANT_BOOL capture
)
3607 EventTarget
*This
= impl_from_IEventTarget(iface
);
3608 listener_type_t listener_type
= capture
? LISTENER_TYPE_CAPTURE
: LISTENER_TYPE_BUBBLE
;
3609 listener_container_t
*container
;
3610 event_listener_t
*listener
;
3612 TRACE("(%p)->(%s %p %x)\n", This
, debugstr_w(type
), function
, capture
);
3614 container
= get_listener_container(This
, type
, TRUE
);
3616 return E_OUTOFMEMORY
;
3618 /* check for duplicates */
3619 LIST_FOR_EACH_ENTRY(listener
, &container
->listeners
, event_listener_t
, entry
) {
3620 if(listener
->type
== listener_type
&& listener
->function
== function
)
3624 listener
= heap_alloc(sizeof(*listener
));
3626 return E_OUTOFMEMORY
;
3628 listener
->type
= listener_type
;
3629 IDispatch_AddRef(listener
->function
= function
);
3630 list_add_tail(&container
->listeners
, &listener
->entry
);
3634 static HRESULT WINAPI
EventTarget_removeEventListener(IEventTarget
*iface
, BSTR type
,
3635 IDispatch
*listener
, VARIANT_BOOL capture
)
3637 EventTarget
*This
= impl_from_IEventTarget(iface
);
3639 TRACE("(%p)->(%s %p %x)\n", This
, debugstr_w(type
), listener
, capture
);
3641 remove_event_listener(This
, type
, capture
? LISTENER_TYPE_CAPTURE
: LISTENER_TYPE_BUBBLE
, listener
);
3645 static HRESULT WINAPI
EventTarget_dispatchEvent(IEventTarget
*iface
, IDOMEvent
*event_iface
, VARIANT_BOOL
*result
)
3647 EventTarget
*This
= impl_from_IEventTarget(iface
);
3648 DOMEvent
*event
= unsafe_impl_from_IDOMEvent(event_iface
);
3650 TRACE("(%p)->(%p %p)\n", This
, event
, result
);
3653 WARN("Invalid event\n");
3654 return E_INVALIDARG
;
3657 return dispatch_event_object(This
, event
, DISPATCH_STANDARD
, result
);
3660 static HRESULT
IEventTarget_addEventListener_hook(DispatchEx
*dispex
, WORD flags
,
3661 DISPPARAMS
*dp
, VARIANT
*res
, EXCEPINFO
*ei
, IServiceProvider
*caller
)
3663 /* If only two arguments were given, implicitly set capture to false */
3664 if((flags
& DISPATCH_METHOD
) && dp
->cArgs
== 2 && !dp
->cNamedArgs
) {
3666 DISPPARAMS new_dp
= {args
, NULL
, 3, 0};
3667 V_VT(args
) = VT_BOOL
;
3668 V_BOOL(args
) = VARIANT_FALSE
;
3669 args
[1] = dp
->rgvarg
[0];
3670 args
[2] = dp
->rgvarg
[1];
3672 TRACE("implicit capture\n");
3674 return dispex_call_builtin(dispex
, DISPID_IEVENTTARGET_ADDEVENTLISTENER
, &new_dp
, res
, ei
, caller
);
3677 return S_FALSE
; /* fallback to default */
3680 static HRESULT
IEventTarget_removeEventListener_hook(DispatchEx
*dispex
, WORD flags
,
3681 DISPPARAMS
*dp
, VARIANT
*res
, EXCEPINFO
*ei
, IServiceProvider
*caller
)
3683 /* If only two arguments were given, implicitly set capture to false */
3684 if((flags
& DISPATCH_METHOD
) && dp
->cArgs
== 2 && !dp
->cNamedArgs
) {
3686 DISPPARAMS new_dp
= {args
, NULL
, 3, 0};
3687 V_VT(args
) = VT_BOOL
;
3688 V_BOOL(args
) = VARIANT_FALSE
;
3689 args
[1] = dp
->rgvarg
[0];
3690 args
[2] = dp
->rgvarg
[1];
3692 TRACE("implicit capture\n");
3694 return dispex_call_builtin(dispex
, DISPID_IEVENTTARGET_REMOVEEVENTLISTENER
, &new_dp
, res
, ei
, caller
);
3697 return S_FALSE
; /* fallback to default */
3700 static const IEventTargetVtbl EventTargetVtbl
= {
3701 EventTarget_QueryInterface
,
3703 EventTarget_Release
,
3704 EventTarget_GetTypeInfoCount
,
3705 EventTarget_GetTypeInfo
,
3706 EventTarget_GetIDsOfNames
,
3708 EventTarget_addEventListener
,
3709 EventTarget_removeEventListener
,
3710 EventTarget_dispatchEvent
3713 static EventTarget
*unsafe_impl_from_IEventTarget(IEventTarget
*iface
)
3715 return iface
&& iface
->lpVtbl
== &EventTargetVtbl
? impl_from_IEventTarget(iface
) : NULL
;
3718 static HRESULT
get_gecko_target(IEventTarget
*target
, nsIDOMEventTarget
**ret
)
3720 EventTarget
*event_target
= unsafe_impl_from_IEventTarget(target
);
3721 const event_target_vtbl_t
*vtbl
;
3725 WARN("Not our IEventTarget implementation\n");
3726 return E_INVALIDARG
;
3729 vtbl
= (const event_target_vtbl_t
*)dispex_get_vtbl(&event_target
->dispex
);
3730 nsres
= nsISupports_QueryInterface(vtbl
->get_gecko_target(&event_target
->dispex
),
3731 &IID_nsIDOMEventTarget
, (void**)ret
);
3732 assert(nsres
== NS_OK
);
3736 HRESULT
EventTarget_QI(EventTarget
*event_target
, REFIID riid
, void **ppv
)
3738 if(IsEqualGUID(riid
, &IID_IEventTarget
)) {
3739 if(use_event_quirks(event_target
)) {
3740 WARN("IEventTarget queried, but not supported by in document mode\n");
3742 return E_NOINTERFACE
;
3744 IEventTarget_AddRef(&event_target
->IEventTarget_iface
);
3745 *ppv
= &event_target
->IEventTarget_iface
;
3749 if(dispex_query_interface(&event_target
->dispex
, riid
, ppv
))
3750 return *ppv
? S_OK
: E_NOINTERFACE
;
3752 WARN("(%p)->(%s %p)\n", event_target
, debugstr_mshtml_guid(riid
), ppv
);
3754 return E_NOINTERFACE
;
3757 void EventTarget_init_dispex_info(dispex_data_t
*dispex_info
, compat_mode_t compat_mode
)
3759 static const dispex_hook_t IEventTarget_hooks
[] = {
3760 {DISPID_IEVENTTARGET_ADDEVENTLISTENER
, IEventTarget_addEventListener_hook
},
3761 {DISPID_IEVENTTARGET_REMOVEEVENTLISTENER
, IEventTarget_removeEventListener_hook
},
3765 if(compat_mode
>= COMPAT_MODE_IE9
)
3766 dispex_info_add_interface(dispex_info
, IEventTarget_tid
, IEventTarget_hooks
);
3769 static int event_id_cmp(const void *key
, const struct wine_rb_entry
*entry
)
3771 return wcscmp(key
, WINE_RB_ENTRY_VALUE(entry
, listener_container_t
, entry
)->type
);
3774 void EventTarget_Init(EventTarget
*event_target
, IUnknown
*outer
, dispex_static_data_t
*dispex_data
,
3775 compat_mode_t compat_mode
)
3777 init_dispatch(&event_target
->dispex
, outer
, dispex_data
, compat_mode
);
3778 event_target
->IEventTarget_iface
.lpVtbl
= &EventTargetVtbl
;
3779 wine_rb_init(&event_target
->handler_map
, event_id_cmp
);
3782 void release_event_target(EventTarget
*event_target
)
3784 listener_container_t
*iter
, *iter2
;
3786 WINE_RB_FOR_EACH_ENTRY_DESTRUCTOR(iter
, iter2
, &event_target
->handler_map
, listener_container_t
, entry
) {
3787 while(!list_empty(&iter
->listeners
)) {
3788 event_listener_t
*listener
= LIST_ENTRY(list_head(&iter
->listeners
), event_listener_t
, entry
);
3789 if(listener
->function
)
3790 IDispatch_Release(listener
->function
);
3791 list_remove(&listener
->entry
);
3792 heap_free(listener
);