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
;
62 /* Keep inherited event types after the inheritor (e.g. DragEvent->MouseEvent->UIEvent) */
71 EVENT_TYPE_PAGETRANSITION
,
78 static const WCHAR
*event_types
[] = {
86 L
"PageTransitionEvent",
100 /* Use Gecko default listener (it's registered on window object for DOM nodes). */
101 #define EVENT_DEFAULTLISTENER 0x0001
102 /* Register Gecko listener on target itself (unlike EVENT_DEFAULTLISTENER). */
103 #define EVENT_BIND_TO_TARGET 0x0002
104 /* Event bubbles by default (unless explicitly specified otherwise). */
105 #define EVENT_BUBBLES 0x0004
106 /* Event is cancelable by default (unless explicitly specified otherwise). */
107 #define EVENT_CANCELABLE 0x0008
108 /* Event may have default handler (so we always have to register Gecko listener). */
109 #define EVENT_HASDEFAULTHANDLERS 0x0020
110 /* Ecent is not supported properly, print FIXME message when it's used. */
111 #define EVENT_FIXME 0x0040
113 /* mouse event flags for fromElement and toElement implementation */
114 #define EVENT_MOUSE_TO_RELATED 0x0100
115 #define EVENT_MOUSE_FROM_RELATED 0x0200
117 /* Keep these sorted case sensitively */
118 static const event_info_t event_info
[] = {
119 {L
"DOMContentLoaded", EVENT_TYPE_EVENT
, 0,
120 EVENT_BUBBLES
| EVENT_CANCELABLE
},
121 {L
"abort", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONABORT
,
122 EVENT_BIND_TO_TARGET
},
123 {L
"afterprint", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONAFTERPRINT
,
124 EVENT_DEFAULTLISTENER
},
125 {L
"animationend", EVENT_TYPE_EVENT
, DISPID_EVPROP_ONANIMATIONEND
,
126 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
},
127 {L
"animationstart", EVENT_TYPE_EVENT
, DISPID_EVPROP_ONANIMATIONSTART
,
128 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
},
129 {L
"beforeactivate", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONBEFOREACTIVATE
,
130 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
131 {L
"beforeprint", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONBEFOREPRINT
,
132 EVENT_DEFAULTLISTENER
},
133 {L
"beforeunload", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONBEFOREUNLOAD
,
134 EVENT_DEFAULTLISTENER
| EVENT_CANCELABLE
},
135 {L
"blur", EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONBLUR
,
136 EVENT_DEFAULTLISTENER
},
137 {L
"change", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONCHANGE
,
138 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
},
139 {L
"click", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONCLICK
,
140 EVENT_DEFAULTLISTENER
| EVENT_HASDEFAULTHANDLERS
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
141 {L
"contextmenu", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONCONTEXTMENU
,
142 EVENT_BUBBLES
| EVENT_CANCELABLE
},
143 {L
"dataavailable", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONDATAAVAILABLE
,
144 EVENT_FIXME
| EVENT_BUBBLES
},
145 {L
"dblclick", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONDBLCLICK
,
146 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
147 {L
"drag", EVENT_TYPE_DRAG
, DISPID_EVMETH_ONDRAG
,
148 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
149 {L
"dragstart", EVENT_TYPE_DRAG
, DISPID_EVMETH_ONDRAGSTART
,
150 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
151 {L
"error", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONERROR
,
152 EVENT_BIND_TO_TARGET
},
153 {L
"focus", EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONFOCUS
,
154 EVENT_DEFAULTLISTENER
},
155 {L
"focusin", EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONFOCUSIN
,
157 {L
"focusout", EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONFOCUSOUT
,
159 {L
"help", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONHELP
,
160 EVENT_BUBBLES
| EVENT_CANCELABLE
},
161 {L
"input", EVENT_TYPE_EVENT
, DISPID_UNKNOWN
,
162 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
},
163 {L
"keydown", EVENT_TYPE_KEYBOARD
, DISPID_EVMETH_ONKEYDOWN
,
164 EVENT_DEFAULTLISTENER
| EVENT_HASDEFAULTHANDLERS
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
165 {L
"keypress", EVENT_TYPE_KEYBOARD
, DISPID_EVMETH_ONKEYPRESS
,
166 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
167 {L
"keyup", EVENT_TYPE_KEYBOARD
, DISPID_EVMETH_ONKEYUP
,
168 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
169 {L
"load", EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONLOAD
,
170 EVENT_BIND_TO_TARGET
},
171 {L
"loadend", EVENT_TYPE_PROGRESS
, DISPID_EVPROP_LOADEND
,
172 EVENT_BIND_TO_TARGET
},
173 {L
"loadstart", EVENT_TYPE_PROGRESS
, DISPID_EVPROP_LOADSTART
,
174 EVENT_BIND_TO_TARGET
},
175 {L
"message", EVENT_TYPE_MESSAGE
, DISPID_EVMETH_ONMESSAGE
,
177 {L
"mousedown", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEDOWN
,
178 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
179 {L
"mousemove", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEMOVE
,
180 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
| EVENT_MOUSE_FROM_RELATED
},
181 {L
"mouseout", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEOUT
,
182 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
| EVENT_MOUSE_TO_RELATED
},
183 {L
"mouseover", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEOVER
,
184 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
| EVENT_MOUSE_FROM_RELATED
},
185 {L
"mouseup", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEUP
,
186 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
187 {L
"mousewheel", EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEWHEEL
,
189 {L
"msthumbnailclick", EVENT_TYPE_MOUSE
, DISPID_EVPROP_ONMSTHUMBNAILCLICK
,
191 {L
"pagehide", EVENT_TYPE_PAGETRANSITION
, DISPID_EVPROP_ONPAGEHIDE
,
193 {L
"pageshow", EVENT_TYPE_PAGETRANSITION
, DISPID_EVPROP_ONPAGESHOW
,
195 {L
"paste", EVENT_TYPE_CLIPBOARD
, DISPID_EVMETH_ONPASTE
,
196 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
197 {L
"progress", EVENT_TYPE_PROGRESS
, DISPID_EVPROP_PROGRESS
,
198 EVENT_BIND_TO_TARGET
},
199 {L
"readystatechange", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONREADYSTATECHANGE
,
201 {L
"resize", EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONRESIZE
,
202 EVENT_DEFAULTLISTENER
},
203 {L
"scroll", EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONSCROLL
,
204 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
/* FIXME: not for elements */},
205 {L
"selectionchange", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONSELECTIONCHANGE
,
207 {L
"selectstart", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONSELECTSTART
,
208 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
209 {L
"storage", EVENT_TYPE_STORAGE
, DISPID_EVMETH_ONSTORAGE
,
211 {L
"storagecommit", EVENT_TYPE_STORAGE
, DISPID_EVMETH_ONSTORAGECOMMIT
,
213 {L
"submit", EVENT_TYPE_EVENT
, DISPID_EVMETH_ONSUBMIT
,
214 EVENT_DEFAULTLISTENER
| EVENT_HASDEFAULTHANDLERS
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
215 {L
"timeout", EVENT_TYPE_PROGRESS
, DISPID_EVPROP_TIMEOUT
,
216 EVENT_BIND_TO_TARGET
},
217 {L
"unload", EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONUNLOAD
,
218 EVENT_BIND_TO_TARGET
},
219 {L
"visibilitychange", EVENT_TYPE_EVENT
, DISPID_EVPROP_VISIBILITYCHANGE
,
220 EVENT_FIXME
| EVENT_BUBBLES
},
222 /* EVENTID_LAST special entry */
223 {NULL
, EVENT_TYPE_EVENT
, 0, 0}
226 C_ASSERT(ARRAY_SIZE(event_info
) - 1 == EVENTID_LAST
);
228 static eventid_t
str_to_eid(const WCHAR
*str
)
230 unsigned i
, a
= 0, b
= ARRAY_SIZE(event_info
) - 1;
235 if(!(c
= wcscmp(event_info
[i
].name
, str
)))
244 static eventid_t
attr_to_eid(const WCHAR
*str
)
246 unsigned i
, a
= 0, b
= ARRAY_SIZE(event_info
) - 1;
249 if((str
[0] != 'o' && str
[0] != 'O') || (str
[1] != 'n' && str
[1] != 'N'))
254 if(!(c
= wcscmp(event_info
[i
].name
, str
+2)))
255 return event_info
[i
].dispid
? i
: EVENTID_LAST
;
263 const WCHAR
*get_event_name(eventid_t eid
)
265 return event_info
[eid
].name
;
268 static listener_container_t
*get_listener_container(EventTarget
*event_target
, const WCHAR
*type
, BOOL alloc
)
270 const event_target_vtbl_t
*vtbl
;
271 listener_container_t
*container
;
272 struct wine_rb_entry
*entry
;
276 entry
= wine_rb_get(&event_target
->handler_map
, type
);
278 return WINE_RB_ENTRY_VALUE(entry
, listener_container_t
, entry
);
282 eid
= str_to_eid(type
);
283 if(event_info
[eid
].flags
& EVENT_FIXME
)
284 FIXME("unimplemented event %s\n", debugstr_w(event_info
[eid
].name
));
286 type_len
= lstrlenW(type
);
287 container
= malloc(FIELD_OFFSET(listener_container_t
, type
[type_len
+1]));
290 memcpy(container
->type
, type
, (type_len
+ 1) * sizeof(WCHAR
));
291 list_init(&container
->listeners
);
292 vtbl
= dispex_get_vtbl(&event_target
->dispex
);
293 if (!vtbl
->bind_event
)
294 FIXME("Unsupported event binding on target %p\n", event_target
);
295 else if(eid
!= EVENTID_LAST
)
296 vtbl
->bind_event(&event_target
->dispex
, eid
);
298 wine_rb_put(&event_target
->handler_map
, container
->type
, &container
->entry
);
302 static void remove_event_listener(EventTarget
*event_target
, const WCHAR
*type_name
, listener_type_t type
, IDispatch
*function
)
304 listener_container_t
*container
;
305 event_listener_t
*listener
;
307 container
= get_listener_container(event_target
, type_name
, FALSE
);
311 LIST_FOR_EACH_ENTRY(listener
, &container
->listeners
, event_listener_t
, entry
) {
312 if(listener
->function
== function
&& listener
->type
== type
) {
313 IDispatch_Release(listener
->function
);
314 list_remove(&listener
->entry
);
321 static HRESULT
get_gecko_target(IEventTarget
*,nsIDOMEventTarget
**);
325 IDOMUIEvent IDOMUIEvent_iface
;
326 nsIDOMUIEvent
*nsevent
;
329 static DOMUIEvent
*DOMUIEvent_from_DOMEvent(DOMEvent
*event
)
331 return CONTAINING_RECORD(event
, DOMUIEvent
, event
);
336 IHTMLEventObj IHTMLEventObj_iface
;
341 VARIANT return_value
;
344 static inline HTMLEventObj
*impl_from_IHTMLEventObj(IHTMLEventObj
*iface
)
346 return CONTAINING_RECORD(iface
, HTMLEventObj
, IHTMLEventObj_iface
);
349 static HRESULT WINAPI
HTMLEventObj_QueryInterface(IHTMLEventObj
*iface
, REFIID riid
, void **ppv
)
351 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
353 TRACE("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
355 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
356 *ppv
= &This
->IHTMLEventObj_iface
;
357 }else if(IsEqualGUID(&IID_IHTMLEventObj
, riid
)) {
358 *ppv
= &This
->IHTMLEventObj_iface
;
359 }else if(dispex_query_interface(&This
->dispex
, riid
, ppv
)) {
360 return *ppv
? S_OK
: E_NOINTERFACE
;
363 WARN("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
364 return E_NOINTERFACE
;
367 IUnknown_AddRef((IUnknown
*)*ppv
);
371 static ULONG WINAPI
HTMLEventObj_AddRef(IHTMLEventObj
*iface
)
373 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
374 LONG ref
= InterlockedIncrement(&This
->ref
);
376 TRACE("(%p) ref=%ld\n", This
, ref
);
381 static ULONG WINAPI
HTMLEventObj_Release(IHTMLEventObj
*iface
)
383 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
384 LONG ref
= InterlockedDecrement(&This
->ref
);
386 TRACE("(%p) ref=%ld\n", This
, ref
);
390 IDOMEvent_Release(&This
->event
->IDOMEvent_iface
);
391 release_dispex(&This
->dispex
);
398 static HRESULT WINAPI
HTMLEventObj_GetTypeInfoCount(IHTMLEventObj
*iface
, UINT
*pctinfo
)
400 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
401 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
404 static HRESULT WINAPI
HTMLEventObj_GetTypeInfo(IHTMLEventObj
*iface
, UINT iTInfo
,
405 LCID lcid
, ITypeInfo
**ppTInfo
)
407 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
408 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
411 static HRESULT WINAPI
HTMLEventObj_GetIDsOfNames(IHTMLEventObj
*iface
, REFIID riid
,
412 LPOLESTR
*rgszNames
, UINT cNames
,
413 LCID lcid
, DISPID
*rgDispId
)
415 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
416 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
420 static HRESULT WINAPI
HTMLEventObj_Invoke(IHTMLEventObj
*iface
, DISPID dispIdMember
,
421 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
422 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
424 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
425 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
426 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
429 static HRESULT WINAPI
HTMLEventObj_get_srcElement(IHTMLEventObj
*iface
, IHTMLElement
**p
)
431 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
433 TRACE("(%p)->(%p)\n", This
, p
);
440 return IDOMEvent_get_srcElement(&This
->event
->IDOMEvent_iface
, p
);
443 static HRESULT WINAPI
HTMLEventObj_get_altKey(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
445 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
446 IDOMKeyboardEvent
*keyboard_event
;
447 IDOMMouseEvent
*mouse_event
;
448 cpp_bool ret
= FALSE
;
450 TRACE("(%p)->(%p)\n", This
, p
);
452 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
453 HRESULT hres
= IDOMMouseEvent_get_altKey(mouse_event
, p
);
454 IDOMMouseEvent_Release(mouse_event
);
458 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMKeyboardEvent
, (void**)&keyboard_event
))) {
459 HRESULT hres
= IDOMKeyboardEvent_get_altKey(keyboard_event
, p
);
460 IDOMKeyboardEvent_Release(keyboard_event
);
464 *p
= variant_bool(ret
);
468 static HRESULT WINAPI
HTMLEventObj_get_ctrlKey(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
470 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
471 IDOMKeyboardEvent
*keyboard_event
;
472 IDOMMouseEvent
*mouse_event
;
473 cpp_bool ret
= FALSE
;
475 TRACE("(%p)->(%p)\n", This
, p
);
477 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
478 HRESULT hres
= IDOMMouseEvent_get_ctrlKey(mouse_event
, p
);
479 IDOMMouseEvent_Release(mouse_event
);
483 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMKeyboardEvent
, (void**)&keyboard_event
))) {
484 HRESULT hres
= IDOMKeyboardEvent_get_ctrlKey(keyboard_event
, p
);
485 IDOMKeyboardEvent_Release(keyboard_event
);
489 *p
= variant_bool(ret
);
493 static HRESULT WINAPI
HTMLEventObj_get_shiftKey(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
495 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
496 IDOMKeyboardEvent
*keyboard_event
;
497 IDOMMouseEvent
*mouse_event
;
498 cpp_bool ret
= FALSE
;
500 TRACE("(%p)->(%p)\n", This
, p
);
502 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
503 HRESULT hres
= IDOMMouseEvent_get_shiftKey(mouse_event
, p
);
504 IDOMMouseEvent_Release(mouse_event
);
508 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMKeyboardEvent
, (void**)&keyboard_event
))) {
509 HRESULT hres
= IDOMKeyboardEvent_get_shiftKey(keyboard_event
, p
);
510 IDOMKeyboardEvent_Release(keyboard_event
);
514 *p
= variant_bool(ret
);
518 static HRESULT WINAPI
HTMLEventObj_put_returnValue(IHTMLEventObj
*iface
, VARIANT v
)
520 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
522 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&v
));
524 if(V_VT(&v
) != VT_BOOL
) {
525 FIXME("unsupported value %s\n", debugstr_variant(&v
));
526 return DISP_E_BADVARTYPE
;
529 This
->return_value
= v
;
530 if(!V_BOOL(&v
) && This
->event
)
531 IDOMEvent_preventDefault(&This
->event
->IDOMEvent_iface
);
535 static HRESULT WINAPI
HTMLEventObj_get_returnValue(IHTMLEventObj
*iface
, VARIANT
*p
)
537 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
539 TRACE("(%p)->(%p)\n", This
, p
);
542 return VariantCopy(p
, &This
->return_value
);
545 static HRESULT WINAPI
HTMLEventObj_put_cancelBubble(IHTMLEventObj
*iface
, VARIANT_BOOL v
)
547 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
549 TRACE("(%p)->(%x)\n", This
, v
);
552 IDOMEvent_stopPropagation(&This
->event
->IDOMEvent_iface
);
556 static HRESULT WINAPI
HTMLEventObj_get_cancelBubble(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
558 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
560 TRACE("(%p)->(%p)\n", This
, p
);
562 *p
= variant_bool(This
->event
&& This
->event
->stop_propagation
);
566 static HRESULT WINAPI
HTMLEventObj_get_fromElement(IHTMLEventObj
*iface
, IHTMLElement
**p
)
568 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
569 IDOMMouseEvent
*mouse_event
;
571 TRACE("(%p)->(%p)\n", This
, p
);
573 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
574 HRESULT hres
= IDOMMouseEvent_get_fromElement(mouse_event
, p
);
575 IDOMMouseEvent_Release(mouse_event
);
583 static HRESULT WINAPI
HTMLEventObj_get_toElement(IHTMLEventObj
*iface
, IHTMLElement
**p
)
585 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
586 IDOMMouseEvent
*mouse_event
;
588 TRACE("(%p)->(%p)\n", This
, p
);
590 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
591 HRESULT hres
= IDOMMouseEvent_get_toElement(mouse_event
, p
);
592 IDOMMouseEvent_Release(mouse_event
);
600 static HRESULT WINAPI
HTMLEventObj_put_keyCode(IHTMLEventObj
*iface
, LONG v
)
602 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
603 FIXME("(%p)->(%ld)\n", This
, v
);
607 static HRESULT WINAPI
HTMLEventObj_get_keyCode(IHTMLEventObj
*iface
, LONG
*p
)
609 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
610 IDOMKeyboardEvent
*keyboard_event
;
612 TRACE("(%p)->(%p)\n", This
, p
);
614 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMKeyboardEvent
, (void**)&keyboard_event
))) {
615 HRESULT hres
= IDOMKeyboardEvent_get_keyCode(keyboard_event
, p
);
616 IDOMKeyboardEvent_Release(keyboard_event
);
624 static HRESULT WINAPI
HTMLEventObj_get_button(IHTMLEventObj
*iface
, LONG
*p
)
626 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
627 IDOMMouseEvent
*mouse_event
;
630 TRACE("(%p)->(%p)\n", This
, p
);
632 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
633 HRESULT hres
= IDOMMouseEvent_get_button(mouse_event
, &button
);
634 IDOMMouseEvent_Release(mouse_event
);
643 static HRESULT WINAPI
HTMLEventObj_get_type(IHTMLEventObj
*iface
, BSTR
*p
)
645 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
647 TRACE("(%p)->(%p)\n", This
, p
);
654 return IDOMEvent_get_type(&This
->event
->IDOMEvent_iface
, p
);
657 static HRESULT WINAPI
HTMLEventObj_get_qualifier(IHTMLEventObj
*iface
, BSTR
*p
)
659 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
661 FIXME("(%p)->(%p)\n", This
, p
);
667 static HRESULT WINAPI
HTMLEventObj_get_reason(IHTMLEventObj
*iface
, LONG
*p
)
669 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
671 FIXME("(%p)->(%p)\n", This
, p
);
677 static HRESULT WINAPI
HTMLEventObj_get_x(IHTMLEventObj
*iface
, LONG
*p
)
679 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
682 TRACE("(%p)->(%p)\n", This
, p
);
685 nsIDOMUIEvent
*ui_event
;
686 nsresult nsres
= nsIDOMEvent_QueryInterface(This
->event
->nsevent
, &IID_nsIDOMUIEvent
, (void**)&ui_event
);
688 if(NS_SUCCEEDED(nsres
)) {
689 /* NOTE: pageX is not exactly right here. */
690 nsres
= nsIDOMUIEvent_GetPageX(ui_event
, &x
);
691 assert(nsres
== NS_OK
);
692 nsIDOMUIEvent_Release(ui_event
);
700 static HRESULT WINAPI
HTMLEventObj_get_y(IHTMLEventObj
*iface
, LONG
*p
)
702 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
705 TRACE("(%p)->(%p)\n", This
, p
);
708 nsIDOMUIEvent
*ui_event
;
709 nsresult nsres
= nsIDOMEvent_QueryInterface(This
->event
->nsevent
, &IID_nsIDOMUIEvent
, (void**)&ui_event
);
711 if(NS_SUCCEEDED(nsres
)) {
712 /* NOTE: pageY is not exactly right here. */
713 nsres
= nsIDOMUIEvent_GetPageY(ui_event
, &y
);
714 assert(nsres
== NS_OK
);
715 nsIDOMUIEvent_Release(ui_event
);
723 static HRESULT WINAPI
HTMLEventObj_get_clientX(IHTMLEventObj
*iface
, LONG
*p
)
725 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
726 IDOMMouseEvent
*mouse_event
;
728 TRACE("(%p)->(%p)\n", This
, p
);
730 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
731 HRESULT hres
= IDOMMouseEvent_get_clientX(mouse_event
, p
);
732 IDOMMouseEvent_Release(mouse_event
);
740 static HRESULT WINAPI
HTMLEventObj_get_clientY(IHTMLEventObj
*iface
, LONG
*p
)
742 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
743 IDOMMouseEvent
*mouse_event
;
745 TRACE("(%p)->(%p)\n", This
, p
);
747 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
748 HRESULT hres
= IDOMMouseEvent_get_clientY(mouse_event
, p
);
749 IDOMMouseEvent_Release(mouse_event
);
757 static HRESULT WINAPI
HTMLEventObj_get_offsetX(IHTMLEventObj
*iface
, LONG
*p
)
759 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
760 IDOMMouseEvent
*mouse_event
;
762 TRACE("(%p)->(%p)\n", This
, p
);
764 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
765 HRESULT hres
= IDOMMouseEvent_get_offsetX(mouse_event
, p
);
766 IDOMMouseEvent_Release(mouse_event
);
774 static HRESULT WINAPI
HTMLEventObj_get_offsetY(IHTMLEventObj
*iface
, LONG
*p
)
776 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
777 IDOMMouseEvent
*mouse_event
;
779 TRACE("(%p)->(%p)\n", This
, p
);
781 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
782 HRESULT hres
= IDOMMouseEvent_get_offsetY(mouse_event
, p
);
783 IDOMMouseEvent_Release(mouse_event
);
791 static HRESULT WINAPI
HTMLEventObj_get_screenX(IHTMLEventObj
*iface
, LONG
*p
)
793 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
794 IDOMMouseEvent
*mouse_event
;
796 TRACE("(%p)->(%p)\n", This
, p
);
798 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
799 HRESULT hres
= IDOMMouseEvent_get_screenX(mouse_event
, p
);
800 IDOMMouseEvent_Release(mouse_event
);
808 static HRESULT WINAPI
HTMLEventObj_get_screenY(IHTMLEventObj
*iface
, LONG
*p
)
810 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
811 IDOMMouseEvent
*mouse_event
;
813 TRACE("(%p)->(%p)\n", This
, p
);
815 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
816 HRESULT hres
= IDOMMouseEvent_get_screenY(mouse_event
, p
);
817 IDOMMouseEvent_Release(mouse_event
);
825 static HRESULT WINAPI
HTMLEventObj_get_srcFilter(IHTMLEventObj
*iface
, IDispatch
**p
)
827 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
829 FIXME("(%p)->(%p)\n", This
, p
);
835 static const IHTMLEventObjVtbl HTMLEventObjVtbl
= {
836 HTMLEventObj_QueryInterface
,
838 HTMLEventObj_Release
,
839 HTMLEventObj_GetTypeInfoCount
,
840 HTMLEventObj_GetTypeInfo
,
841 HTMLEventObj_GetIDsOfNames
,
843 HTMLEventObj_get_srcElement
,
844 HTMLEventObj_get_altKey
,
845 HTMLEventObj_get_ctrlKey
,
846 HTMLEventObj_get_shiftKey
,
847 HTMLEventObj_put_returnValue
,
848 HTMLEventObj_get_returnValue
,
849 HTMLEventObj_put_cancelBubble
,
850 HTMLEventObj_get_cancelBubble
,
851 HTMLEventObj_get_fromElement
,
852 HTMLEventObj_get_toElement
,
853 HTMLEventObj_put_keyCode
,
854 HTMLEventObj_get_keyCode
,
855 HTMLEventObj_get_button
,
856 HTMLEventObj_get_type
,
857 HTMLEventObj_get_qualifier
,
858 HTMLEventObj_get_reason
,
861 HTMLEventObj_get_clientX
,
862 HTMLEventObj_get_clientY
,
863 HTMLEventObj_get_offsetX
,
864 HTMLEventObj_get_offsetY
,
865 HTMLEventObj_get_screenX
,
866 HTMLEventObj_get_screenY
,
867 HTMLEventObj_get_srcFilter
870 static inline HTMLEventObj
*unsafe_impl_from_IHTMLEventObj(IHTMLEventObj
*iface
)
872 return iface
->lpVtbl
== &HTMLEventObjVtbl
? impl_from_IHTMLEventObj(iface
) : NULL
;
875 static const tid_t HTMLEventObj_iface_tids
[] = {
880 static dispex_static_data_t HTMLEventObj_dispex
= {
884 HTMLEventObj_iface_tids
887 static HTMLEventObj
*alloc_event_obj(DOMEvent
*event
, compat_mode_t compat_mode
)
889 HTMLEventObj
*event_obj
;
891 event_obj
= calloc(1, sizeof(*event_obj
));
895 event_obj
->IHTMLEventObj_iface
.lpVtbl
= &HTMLEventObjVtbl
;
897 event_obj
->event
= event
;
899 IDOMEvent_AddRef(&event
->IDOMEvent_iface
);
901 init_dispatch(&event_obj
->dispex
, (IUnknown
*)&event_obj
->IHTMLEventObj_iface
, &HTMLEventObj_dispex
, compat_mode
);
905 HRESULT
create_event_obj(compat_mode_t compat_mode
, IHTMLEventObj
**ret
)
907 HTMLEventObj
*event_obj
;
909 event_obj
= alloc_event_obj(NULL
, compat_mode
);
911 return E_OUTOFMEMORY
;
913 *ret
= &event_obj
->IHTMLEventObj_iface
;
917 static inline DOMEvent
*impl_from_IDOMEvent(IDOMEvent
*iface
)
919 return CONTAINING_RECORD(iface
, DOMEvent
, IDOMEvent_iface
);
922 static const IDOMEventVtbl DOMEventVtbl
;
924 static inline DOMEvent
*unsafe_impl_from_IDOMEvent(IDOMEvent
*iface
)
926 return iface
&& iface
->lpVtbl
== &DOMEventVtbl
? impl_from_IDOMEvent(iface
) : NULL
;
929 static HRESULT WINAPI
DOMEvent_QueryInterface(IDOMEvent
*iface
, REFIID riid
, void **ppv
)
931 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
933 TRACE("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
935 if(IsEqualGUID(&IID_IUnknown
, riid
))
936 *ppv
= &This
->IDOMEvent_iface
;
937 else if(IsEqualGUID(&IID_IDOMEvent
, riid
))
938 *ppv
= &This
->IDOMEvent_iface
;
939 else if(dispex_query_interface(&This
->dispex
, riid
, ppv
))
940 return *ppv
? S_OK
: E_NOINTERFACE
;
941 else if(!This
->query_interface
|| !(*ppv
= This
->query_interface(This
, riid
))) {
943 WARN("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
944 return E_NOINTERFACE
;
947 IUnknown_AddRef((IUnknown
*)*ppv
);
951 static ULONG WINAPI
DOMEvent_AddRef(IDOMEvent
*iface
)
953 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
954 LONG ref
= InterlockedIncrement(&This
->ref
);
956 TRACE("(%p) ref=%lu\n", This
, ref
);
961 static ULONG WINAPI
DOMEvent_Release(IDOMEvent
*iface
)
963 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
964 LONG ref
= InterlockedDecrement(&This
->ref
);
966 TRACE("(%p) ref=%lu\n", This
, ref
);
972 IEventTarget_Release(&This
->target
->IEventTarget_iface
);
973 nsIDOMEvent_Release(This
->nsevent
);
974 release_dispex(&This
->dispex
);
982 static HRESULT WINAPI
DOMEvent_GetTypeInfoCount(IDOMEvent
*iface
, UINT
*pctinfo
)
984 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
985 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
988 static HRESULT WINAPI
DOMEvent_GetTypeInfo(IDOMEvent
*iface
, UINT iTInfo
,
989 LCID lcid
, ITypeInfo
**ppTInfo
)
991 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
992 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
995 static HRESULT WINAPI
DOMEvent_GetIDsOfNames(IDOMEvent
*iface
, REFIID riid
,
996 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
998 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
999 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1003 static HRESULT WINAPI
DOMEvent_Invoke(IDOMEvent
*iface
, DISPID dispIdMember
,
1004 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1005 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1007 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1008 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1009 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1012 static HRESULT WINAPI
DOMEvent_get_bubbles(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
1014 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1016 TRACE("(%p)->(%p)\n", This
, p
);
1018 *p
= variant_bool(This
->bubbles
);
1022 static HRESULT WINAPI
DOMEvent_get_cancelable(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
1024 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1026 TRACE("(%p)->(%p)\n", This
, p
);
1028 *p
= variant_bool(This
->cancelable
);
1032 static HRESULT WINAPI
DOMEvent_get_currentTarget(IDOMEvent
*iface
, IEventTarget
**p
)
1034 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1036 TRACE("(%p)->(%p)\n", This
, p
);
1038 if(This
->current_target
)
1039 IEventTarget_AddRef(*p
= &This
->current_target
->IEventTarget_iface
);
1045 static HRESULT WINAPI
DOMEvent_get_defaultPrevented(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
1047 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1049 TRACE("(%p)->(%p)\n", This
, p
);
1051 *p
= variant_bool(This
->prevent_default
);
1055 static HRESULT WINAPI
DOMEvent_get_eventPhase(IDOMEvent
*iface
, USHORT
*p
)
1057 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1059 TRACE("(%p)->(%p)\n", This
, p
);
1065 static HRESULT WINAPI
DOMEvent_get_target(IDOMEvent
*iface
, IEventTarget
**p
)
1067 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1069 TRACE("(%p)->(%p)\n", This
, p
);
1072 IEventTarget_AddRef(*p
= &This
->target
->IEventTarget_iface
);
1078 static HRESULT WINAPI
DOMEvent_get_timeStamp(IDOMEvent
*iface
, ULONGLONG
*p
)
1080 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1082 TRACE("(%p)->(%p)\n", This
, p
);
1084 *p
= This
->time_stamp
;
1088 static HRESULT WINAPI
DOMEvent_get_type(IDOMEvent
*iface
, BSTR
*p
)
1090 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1092 TRACE("(%p)->(%p)\n", This
, p
);
1095 *p
= SysAllocString(This
->type
);
1097 return E_OUTOFMEMORY
;
1105 #define nsIDOMEvent_InitEvent(_this,type,bubbles,cancelable) \
1106 ((void (WINAPI*)(void*,nsIDOMEvent*,const nsAString*,cpp_bool,cpp_bool)) \
1107 &call_thiscall_func)((_this)->lpVtbl->InitEvent,_this,type,bubbles,cancelable)
1111 static HRESULT WINAPI
DOMEvent_initEvent(IDOMEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
, VARIANT_BOOL cancelable
)
1113 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1116 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_w(type
), can_bubble
, cancelable
);
1119 TRACE("called on already dispatched event\n");
1124 This
->type
= wcsdup(type
);
1126 return E_OUTOFMEMORY
;
1127 This
->event_id
= str_to_eid(type
);
1129 This
->bubbles
= !!can_bubble
;
1130 This
->cancelable
= !!cancelable
;
1132 nsAString_InitDepend(&nsstr
, type
);
1133 nsIDOMEvent_InitEvent(This
->nsevent
, &nsstr
, This
->bubbles
, This
->cancelable
);
1134 nsAString_Finish(&nsstr
);
1139 static HRESULT WINAPI
DOMEvent_preventDefault(IDOMEvent
*iface
)
1141 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1143 TRACE("(%p)\n", This
);
1145 if(This
->current_target
&& This
->cancelable
) {
1146 This
->prevent_default
= TRUE
;
1147 nsIDOMEvent_PreventDefault(This
->nsevent
);
1152 static HRESULT WINAPI
DOMEvent_stopPropagation(IDOMEvent
*iface
)
1154 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1156 TRACE("(%p)\n", This
);
1158 This
->stop_propagation
= TRUE
;
1159 nsIDOMEvent_StopPropagation(This
->nsevent
);
1163 static HRESULT WINAPI
DOMEvent_stopImmediatePropagation(IDOMEvent
*iface
)
1165 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1167 TRACE("(%p)\n", This
);
1169 This
->stop_immediate_propagation
= This
->stop_propagation
= TRUE
;
1170 nsIDOMEvent_StopImmediatePropagation(This
->nsevent
);
1174 static HRESULT WINAPI
DOMEvent_get_isTrusted(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
1176 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1178 TRACE("(%p)->(%p)\n", This
, p
);
1180 *p
= variant_bool(This
->trusted
);
1184 static HRESULT WINAPI
DOMEvent_put_cancelBubble(IDOMEvent
*iface
, VARIANT_BOOL v
)
1186 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1187 FIXME("(%p)->(%x)\n", This
, v
);
1191 static HRESULT WINAPI
DOMEvent_get_cancelBubble(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
1193 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1194 FIXME("(%p)->(%p)\n", This
, p
);
1198 static HRESULT WINAPI
DOMEvent_get_srcElement(IDOMEvent
*iface
, IHTMLElement
**p
)
1200 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1202 TRACE("(%p)->(%p)\n", This
, p
);
1205 IDispatchEx_QueryInterface(&This
->target
->dispex
.IDispatchEx_iface
, &IID_IHTMLElement
, (void**)p
);
1211 static const IDOMEventVtbl DOMEventVtbl
= {
1212 DOMEvent_QueryInterface
,
1215 DOMEvent_GetTypeInfoCount
,
1216 DOMEvent_GetTypeInfo
,
1217 DOMEvent_GetIDsOfNames
,
1219 DOMEvent_get_bubbles
,
1220 DOMEvent_get_cancelable
,
1221 DOMEvent_get_currentTarget
,
1222 DOMEvent_get_defaultPrevented
,
1223 DOMEvent_get_eventPhase
,
1224 DOMEvent_get_target
,
1225 DOMEvent_get_timeStamp
,
1228 DOMEvent_preventDefault
,
1229 DOMEvent_stopPropagation
,
1230 DOMEvent_stopImmediatePropagation
,
1231 DOMEvent_get_isTrusted
,
1232 DOMEvent_put_cancelBubble
,
1233 DOMEvent_get_cancelBubble
,
1234 DOMEvent_get_srcElement
1237 static inline DOMUIEvent
*impl_from_IDOMUIEvent(IDOMUIEvent
*iface
)
1239 return CONTAINING_RECORD(iface
, DOMUIEvent
, IDOMUIEvent_iface
);
1242 static HRESULT WINAPI
DOMUIEvent_QueryInterface(IDOMUIEvent
*iface
, REFIID riid
, void **ppv
)
1244 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1245 return IDOMEvent_QueryInterface(&This
->event
.IDOMEvent_iface
, riid
, ppv
);
1248 static ULONG WINAPI
DOMUIEvent_AddRef(IDOMUIEvent
*iface
)
1250 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1251 return IDOMEvent_AddRef(&This
->event
.IDOMEvent_iface
);
1254 static ULONG WINAPI
DOMUIEvent_Release(IDOMUIEvent
*iface
)
1256 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1257 return IDOMEvent_Release(&This
->event
.IDOMEvent_iface
);
1260 static HRESULT WINAPI
DOMUIEvent_GetTypeInfoCount(IDOMUIEvent
*iface
, UINT
*pctinfo
)
1262 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1263 return IDispatchEx_GetTypeInfoCount(&This
->event
.dispex
.IDispatchEx_iface
, pctinfo
);
1266 static HRESULT WINAPI
DOMUIEvent_GetTypeInfo(IDOMUIEvent
*iface
, UINT iTInfo
,
1267 LCID lcid
, ITypeInfo
**ppTInfo
)
1269 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1270 return IDispatchEx_GetTypeInfo(&This
->event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1273 static HRESULT WINAPI
DOMUIEvent_GetIDsOfNames(IDOMUIEvent
*iface
, REFIID riid
,
1274 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1276 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1277 return IDispatchEx_GetIDsOfNames(&This
->event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1281 static HRESULT WINAPI
DOMUIEvent_Invoke(IDOMUIEvent
*iface
, DISPID dispIdMember
,
1282 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1283 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1285 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1286 return IDispatchEx_Invoke(&This
->event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1287 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1290 static HRESULT WINAPI
DOMUIEvent_get_view(IDOMUIEvent
*iface
, IHTMLWindow2
**p
)
1292 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1293 mozIDOMWindowProxy
*moz_window
;
1294 HTMLOuterWindow
*view
= NULL
;
1297 TRACE("(%p)->(%p)\n", This
, p
);
1299 nsres
= nsIDOMUIEvent_GetView(This
->nsevent
, &moz_window
);
1300 if(NS_FAILED(nsres
))
1304 view
= mozwindow_to_window(moz_window
);
1305 mozIDOMWindowProxy_Release(moz_window
);
1308 IHTMLWindow2_AddRef((*p
= &view
->base
.inner_window
->base
.IHTMLWindow2_iface
));
1314 static HRESULT WINAPI
DOMUIEvent_get_detail(IDOMUIEvent
*iface
, LONG
*p
)
1316 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1320 TRACE("(%p)->(%p)\n", This
, p
);
1322 nsres
= nsIDOMUIEvent_GetDetail(This
->nsevent
, &detail
);
1323 if(NS_FAILED(nsres
))
1330 static HRESULT WINAPI
DOMUIEvent_initUIEvent(IDOMUIEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
1331 VARIANT_BOOL cancelable
, IHTMLWindow2
*view
, LONG detail
)
1333 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1338 TRACE("(%p)->(%s %x %x %p %lx)\n", This
, debugstr_w(type
), can_bubble
, cancelable
, view
, detail
);
1340 if(This
->event
.target
) {
1341 TRACE("called on already dispatched event\n");
1346 FIXME("view argument is not supported\n");
1348 hres
= IDOMEvent_initEvent(&This
->event
.IDOMEvent_iface
, type
, can_bubble
, cancelable
);
1352 nsAString_InitDepend(&type_str
, type
);
1353 nsres
= nsIDOMUIEvent_InitUIEvent(This
->nsevent
, &type_str
, !!can_bubble
, !!cancelable
,
1354 NULL
/* FIXME */, detail
);
1355 nsAString_Finish(&type_str
);
1356 if(NS_FAILED(nsres
)) {
1357 FIXME("InitUIEvent failed: %08lx\n", nsres
);
1364 static const IDOMUIEventVtbl DOMUIEventVtbl
= {
1365 DOMUIEvent_QueryInterface
,
1368 DOMUIEvent_GetTypeInfoCount
,
1369 DOMUIEvent_GetTypeInfo
,
1370 DOMUIEvent_GetIDsOfNames
,
1372 DOMUIEvent_get_view
,
1373 DOMUIEvent_get_detail
,
1374 DOMUIEvent_initUIEvent
1377 static void *DOMUIEvent_query_interface(DOMEvent
*event
, REFIID riid
)
1379 DOMUIEvent
*This
= DOMUIEvent_from_DOMEvent(event
);
1380 if(IsEqualGUID(&IID_IDOMUIEvent
, riid
))
1381 return &This
->IDOMUIEvent_iface
;
1385 static void DOMUIEvent_destroy(DOMEvent
*event
)
1387 DOMUIEvent
*This
= DOMUIEvent_from_DOMEvent(event
);
1388 nsIDOMUIEvent_Release(This
->nsevent
);
1392 DOMUIEvent ui_event
;
1393 IDOMMouseEvent IDOMMouseEvent_iface
;
1394 nsIDOMMouseEvent
*nsevent
;
1397 static inline DOMMouseEvent
*impl_from_IDOMMouseEvent(IDOMMouseEvent
*iface
)
1399 return CONTAINING_RECORD(iface
, DOMMouseEvent
, IDOMMouseEvent_iface
);
1402 static HRESULT WINAPI
DOMMouseEvent_QueryInterface(IDOMMouseEvent
*iface
, REFIID riid
, void **ppv
)
1404 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1405 return IDOMEvent_QueryInterface(&This
->ui_event
.event
.IDOMEvent_iface
, riid
, ppv
);
1408 static ULONG WINAPI
DOMMouseEvent_AddRef(IDOMMouseEvent
*iface
)
1410 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1411 return IDOMEvent_AddRef(&This
->ui_event
.event
.IDOMEvent_iface
);
1414 static ULONG WINAPI
DOMMouseEvent_Release(IDOMMouseEvent
*iface
)
1416 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1417 return IDOMEvent_Release(&This
->ui_event
.event
.IDOMEvent_iface
);
1420 static HRESULT WINAPI
DOMMouseEvent_GetTypeInfoCount(IDOMMouseEvent
*iface
, UINT
*pctinfo
)
1422 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1423 return IDispatchEx_GetTypeInfoCount(&This
->ui_event
.event
.dispex
.IDispatchEx_iface
, pctinfo
);
1426 static HRESULT WINAPI
DOMMouseEvent_GetTypeInfo(IDOMMouseEvent
*iface
, UINT iTInfo
,
1427 LCID lcid
, ITypeInfo
**ppTInfo
)
1429 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1430 return IDispatchEx_GetTypeInfo(&This
->ui_event
.event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1433 static HRESULT WINAPI
DOMMouseEvent_GetIDsOfNames(IDOMMouseEvent
*iface
, REFIID riid
,
1434 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1436 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1437 return IDispatchEx_GetIDsOfNames(&This
->ui_event
.event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1441 static HRESULT WINAPI
DOMMouseEvent_Invoke(IDOMMouseEvent
*iface
, DISPID dispIdMember
,
1442 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1443 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1445 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1446 return IDispatchEx_Invoke(&This
->ui_event
.event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1447 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1450 static HRESULT WINAPI
DOMMouseEvent_get_screenX(IDOMMouseEvent
*iface
, LONG
*p
)
1452 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1456 TRACE("(%p)->(%p)\n", This
, p
);
1458 nsres
= nsIDOMMouseEvent_GetScreenX(This
->nsevent
, &screen_x
);
1459 if(NS_FAILED(nsres
))
1466 static HRESULT WINAPI
DOMMouseEvent_get_screenY(IDOMMouseEvent
*iface
, LONG
*p
)
1468 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1472 TRACE("(%p)->(%p)\n", This
, p
);
1474 nsres
= nsIDOMMouseEvent_GetScreenY(This
->nsevent
, &screen_y
);
1475 if(NS_FAILED(nsres
))
1482 static HRESULT WINAPI
DOMMouseEvent_get_clientX(IDOMMouseEvent
*iface
, LONG
*p
)
1484 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1488 TRACE("(%p)->(%p)\n", This
, p
);
1490 nsres
= nsIDOMMouseEvent_GetClientX(This
->nsevent
, &client_x
);
1491 if(NS_FAILED(nsres
))
1498 static HRESULT WINAPI
DOMMouseEvent_get_clientY(IDOMMouseEvent
*iface
, LONG
*p
)
1500 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1504 TRACE("(%p)->(%p)\n", This
, p
);
1506 nsres
= nsIDOMMouseEvent_GetClientY(This
->nsevent
, &client_y
);
1507 if(NS_FAILED(nsres
))
1514 static HRESULT WINAPI
DOMMouseEvent_get_ctrlKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1516 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1520 TRACE("(%p)->(%p)\n", This
, p
);
1522 nsres
= nsIDOMMouseEvent_GetCtrlKey(This
->nsevent
, &r
);
1523 if(NS_FAILED(nsres
))
1526 *p
= variant_bool(r
);
1530 static HRESULT WINAPI
DOMMouseEvent_get_shiftKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1532 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1536 TRACE("(%p)->(%p)\n", This
, p
);
1538 nsres
= nsIDOMMouseEvent_GetShiftKey(This
->nsevent
, &r
);
1539 if(NS_FAILED(nsres
))
1542 *p
= variant_bool(r
);
1546 static HRESULT WINAPI
DOMMouseEvent_get_altKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1548 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1552 TRACE("(%p)->(%p)\n", This
, p
);
1554 nsres
= nsIDOMMouseEvent_GetAltKey(This
->nsevent
, &r
);
1555 if(NS_FAILED(nsres
))
1558 *p
= variant_bool(r
);
1562 static HRESULT WINAPI
DOMMouseEvent_get_metaKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1564 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1568 TRACE("(%p)->(%p)\n", This
, p
);
1570 nsres
= nsIDOMMouseEvent_GetMetaKey(This
->nsevent
, &r
);
1571 if(NS_FAILED(nsres
))
1574 *p
= variant_bool(r
);
1578 static HRESULT WINAPI
DOMMouseEvent_get_button(IDOMMouseEvent
*iface
, USHORT
*p
)
1580 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1584 TRACE("(%p)->(%p)\n", This
, p
);
1586 nsres
= nsIDOMMouseEvent_GetButton(This
->nsevent
, &r
);
1587 if(NS_FAILED(nsres
))
1594 static HRESULT WINAPI
DOMMouseEvent_get_relatedTarget(IDOMMouseEvent
*iface
, IEventTarget
**p
)
1596 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1597 nsIDOMEventTarget
*related_target
;
1598 nsIDOMNode
*target_node
;
1603 TRACE("(%p)->(%p)\n", This
, p
);
1605 nsres
= nsIDOMMouseEvent_GetRelatedTarget(This
->nsevent
, &related_target
);
1606 if(NS_FAILED(nsres
))
1609 if(!related_target
) {
1614 nsres
= nsIDOMEventTarget_QueryInterface(related_target
, &IID_nsIDOMNode
, (void**)&target_node
);
1615 nsIDOMEventTarget_Release(related_target
);
1616 if(NS_FAILED(nsres
)) {
1617 FIXME("Only node targets supported\n");
1621 hres
= get_node(target_node
, TRUE
, &node
);
1622 nsIDOMNode_Release(target_node
);
1626 *p
= &node
->event_target
.IEventTarget_iface
;
1630 static HRESULT WINAPI
DOMMouseEvent_initMouseEvent(IDOMMouseEvent
*iface
, BSTR type
,
1631 VARIANT_BOOL can_bubble
, VARIANT_BOOL cancelable
, IHTMLWindow2
*view
, LONG detail
,
1632 LONG screen_x
, LONG screen_y
, LONG client_x
, LONG client_y
, VARIANT_BOOL ctrl_key
,
1633 VARIANT_BOOL alt_key
, VARIANT_BOOL shift_key
, VARIANT_BOOL meta_key
, USHORT button
,
1634 IEventTarget
*related_target
)
1636 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1637 nsIDOMEventTarget
*nstarget
= NULL
;
1642 TRACE("(%p)->(%s %x %x %p %ld %ld %ld %ld %ld %x %x %x %x %u %p)\n", This
, debugstr_w(type
),
1643 can_bubble
, cancelable
, view
, detail
, screen_x
, screen_y
, client_x
, client_y
,
1644 ctrl_key
, alt_key
, shift_key
, meta_key
, button
, related_target
);
1646 if(This
->ui_event
.event
.target
) {
1647 TRACE("called on already dispatched event\n");
1652 FIXME("view argument is not supported\n");
1654 if(related_target
) {
1655 hres
= get_gecko_target(related_target
, &nstarget
);
1660 hres
= IDOMEvent_initEvent(&This
->ui_event
.event
.IDOMEvent_iface
, type
, can_bubble
, cancelable
);
1661 if(SUCCEEDED(hres
)) {
1662 nsAString_InitDepend(&type_str
, type
);
1663 nsres
= nsIDOMMouseEvent_InitMouseEvent(This
->nsevent
, &type_str
, can_bubble
, cancelable
,
1664 NULL
/* FIXME */, detail
, screen_x
, screen_y
,
1665 client_x
, client_y
, !!ctrl_key
, !!alt_key
, !!shift_key
,
1666 !!meta_key
, button
, nstarget
);
1667 nsAString_Finish(&type_str
);
1668 if(NS_FAILED(nsres
)) {
1669 FIXME("InitMouseEvent failed: %08lx\n", nsres
);
1675 nsIDOMEventTarget_Release(nstarget
);
1679 static HRESULT WINAPI
DOMMouseEvent_getModifierState(IDOMMouseEvent
*iface
, BSTR key
,
1680 VARIANT_BOOL
*activated
)
1682 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1683 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(key
), activated
);
1687 static HRESULT WINAPI
DOMMouseEvent_get_buttons(IDOMMouseEvent
*iface
, USHORT
*p
)
1689 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1693 TRACE("(%p)->(%p)\n", This
, p
);
1695 nsres
= nsIDOMMouseEvent_GetButtons(This
->nsevent
, &r
);
1696 if(NS_FAILED(nsres
))
1703 static HRESULT WINAPI
DOMMouseEvent_get_fromElement(IDOMMouseEvent
*iface
, IHTMLElement
**p
)
1705 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1706 eventid_t event_id
= This
->ui_event
.event
.event_id
;
1707 IEventTarget
*related_target
= NULL
;
1708 HRESULT hres
= S_OK
;
1710 TRACE("(%p)->(%p)\n", This
, p
);
1712 if(event_info
[event_id
].flags
& EVENT_MOUSE_FROM_RELATED
)
1713 hres
= IDOMMouseEvent_get_relatedTarget(&This
->IDOMMouseEvent_iface
, &related_target
);
1714 else if(event_info
[event_id
].flags
& EVENT_MOUSE_TO_RELATED
)
1715 hres
= IDOMEvent_get_target(&This
->ui_event
.event
.IDOMEvent_iface
, &related_target
);
1719 if(!related_target
) {
1724 IEventTarget_QueryInterface(related_target
, &IID_IHTMLElement
, (void**)p
);
1728 static HRESULT WINAPI
DOMMouseEvent_get_toElement(IDOMMouseEvent
*iface
, IHTMLElement
**p
)
1730 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1731 eventid_t event_id
= This
->ui_event
.event
.event_id
;
1732 IEventTarget
*related_target
= NULL
;
1733 HRESULT hres
= S_OK
;
1735 TRACE("(%p)->(%p)\n", This
, p
);
1737 if(event_info
[event_id
].flags
& EVENT_MOUSE_TO_RELATED
)
1738 hres
= IDOMMouseEvent_get_relatedTarget(&This
->IDOMMouseEvent_iface
, &related_target
);
1739 else if(event_info
[event_id
].flags
& EVENT_MOUSE_FROM_RELATED
)
1740 hres
= IDOMEvent_get_target(&This
->ui_event
.event
.IDOMEvent_iface
, &related_target
);
1744 if(!related_target
) {
1749 IEventTarget_QueryInterface(related_target
, &IID_IHTMLElement
, (void**)p
);
1753 static HRESULT WINAPI
DOMMouseEvent_get_x(IDOMMouseEvent
*iface
, LONG
*p
)
1755 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1756 FIXME("(%p)->(%p)\n", This
, p
);
1760 static HRESULT WINAPI
DOMMouseEvent_get_y(IDOMMouseEvent
*iface
, LONG
*p
)
1762 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1763 FIXME("(%p)->(%p)\n", This
, p
);
1767 static HRESULT WINAPI
DOMMouseEvent_get_offsetX(IDOMMouseEvent
*iface
, LONG
*p
)
1769 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1771 FIXME("(%p)->(%p) returning 0\n", This
, p
);
1777 static HRESULT WINAPI
DOMMouseEvent_get_offsetY(IDOMMouseEvent
*iface
, LONG
*p
)
1779 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1781 FIXME("(%p)->(%p) returning 0\n", This
, p
);
1787 static HRESULT WINAPI
DOMMouseEvent_get_pageX(IDOMMouseEvent
*iface
, LONG
*p
)
1789 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1793 TRACE("(%p)->(%p)\n", This
, p
);
1795 nsres
= nsIDOMMouseEvent_GetPageX(This
->nsevent
, &r
);
1796 if(NS_FAILED(nsres
))
1803 static HRESULT WINAPI
DOMMouseEvent_get_pageY(IDOMMouseEvent
*iface
, LONG
*p
)
1805 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1809 TRACE("(%p)->(%p)\n", This
, p
);
1811 nsres
= nsIDOMMouseEvent_GetPageY(This
->nsevent
, &r
);
1812 if(NS_FAILED(nsres
))
1819 static HRESULT WINAPI
DOMMouseEvent_get_layerX(IDOMMouseEvent
*iface
, LONG
*p
)
1821 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1825 TRACE("(%p)->(%p)\n", This
, p
);
1827 nsres
= nsIDOMMouseEvent_GetLayerX(This
->nsevent
, &r
);
1828 if(NS_FAILED(nsres
))
1835 static HRESULT WINAPI
DOMMouseEvent_get_layerY(IDOMMouseEvent
*iface
, LONG
*p
)
1837 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1841 TRACE("(%p)->(%p)\n", This
, p
);
1843 nsres
= nsIDOMMouseEvent_GetLayerY(This
->nsevent
, &r
);
1844 if(NS_FAILED(nsres
))
1851 static HRESULT WINAPI
DOMMouseEvent_get_which(IDOMMouseEvent
*iface
, USHORT
*p
)
1853 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1857 TRACE("(%p)->(%p)\n", This
, p
);
1859 nsres
= nsIDOMMouseEvent_GetWhich(This
->nsevent
, &r
);
1860 if(NS_FAILED(nsres
))
1867 static const IDOMMouseEventVtbl DOMMouseEventVtbl
= {
1868 DOMMouseEvent_QueryInterface
,
1869 DOMMouseEvent_AddRef
,
1870 DOMMouseEvent_Release
,
1871 DOMMouseEvent_GetTypeInfoCount
,
1872 DOMMouseEvent_GetTypeInfo
,
1873 DOMMouseEvent_GetIDsOfNames
,
1874 DOMMouseEvent_Invoke
,
1875 DOMMouseEvent_get_screenX
,
1876 DOMMouseEvent_get_screenY
,
1877 DOMMouseEvent_get_clientX
,
1878 DOMMouseEvent_get_clientY
,
1879 DOMMouseEvent_get_ctrlKey
,
1880 DOMMouseEvent_get_shiftKey
,
1881 DOMMouseEvent_get_altKey
,
1882 DOMMouseEvent_get_metaKey
,
1883 DOMMouseEvent_get_button
,
1884 DOMMouseEvent_get_relatedTarget
,
1885 DOMMouseEvent_initMouseEvent
,
1886 DOMMouseEvent_getModifierState
,
1887 DOMMouseEvent_get_buttons
,
1888 DOMMouseEvent_get_fromElement
,
1889 DOMMouseEvent_get_toElement
,
1890 DOMMouseEvent_get_x
,
1891 DOMMouseEvent_get_y
,
1892 DOMMouseEvent_get_offsetX
,
1893 DOMMouseEvent_get_offsetY
,
1894 DOMMouseEvent_get_pageX
,
1895 DOMMouseEvent_get_pageY
,
1896 DOMMouseEvent_get_layerX
,
1897 DOMMouseEvent_get_layerY
,
1898 DOMMouseEvent_get_which
1901 static DOMMouseEvent
*DOMMouseEvent_from_DOMEvent(DOMEvent
*event
)
1903 return CONTAINING_RECORD(event
, DOMMouseEvent
, ui_event
.event
);
1906 static void *DOMMouseEvent_query_interface(DOMEvent
*event
, REFIID riid
)
1908 DOMMouseEvent
*This
= DOMMouseEvent_from_DOMEvent(event
);
1909 if(IsEqualGUID(&IID_IDOMMouseEvent
, riid
))
1910 return &This
->IDOMMouseEvent_iface
;
1911 if(IsEqualGUID(&IID_IDOMUIEvent
, riid
))
1912 return &This
->ui_event
.IDOMUIEvent_iface
;
1916 static void DOMMouseEvent_destroy(DOMEvent
*event
)
1918 DOMMouseEvent
*This
= DOMMouseEvent_from_DOMEvent(event
);
1919 DOMUIEvent_destroy(&This
->ui_event
.event
);
1920 nsIDOMMouseEvent_Release(This
->nsevent
);
1924 DOMUIEvent ui_event
;
1925 IDOMKeyboardEvent IDOMKeyboardEvent_iface
;
1926 nsIDOMKeyEvent
*nsevent
;
1929 static inline DOMKeyboardEvent
*impl_from_IDOMKeyboardEvent(IDOMKeyboardEvent
*iface
)
1931 return CONTAINING_RECORD(iface
, DOMKeyboardEvent
, IDOMKeyboardEvent_iface
);
1934 static HRESULT WINAPI
DOMKeyboardEvent_QueryInterface(IDOMKeyboardEvent
*iface
, REFIID riid
, void **ppv
)
1936 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1937 return IDOMEvent_QueryInterface(&This
->ui_event
.event
.IDOMEvent_iface
, riid
, ppv
);
1940 static ULONG WINAPI
DOMKeyboardEvent_AddRef(IDOMKeyboardEvent
*iface
)
1942 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1943 return IDOMEvent_AddRef(&This
->ui_event
.event
.IDOMEvent_iface
);
1946 static ULONG WINAPI
DOMKeyboardEvent_Release(IDOMKeyboardEvent
*iface
)
1948 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1949 return IDOMEvent_Release(&This
->ui_event
.event
.IDOMEvent_iface
);
1952 static HRESULT WINAPI
DOMKeyboardEvent_GetTypeInfoCount(IDOMKeyboardEvent
*iface
, UINT
*pctinfo
)
1954 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1955 return IDispatchEx_GetTypeInfoCount(&This
->ui_event
.event
.dispex
.IDispatchEx_iface
, pctinfo
);
1958 static HRESULT WINAPI
DOMKeyboardEvent_GetTypeInfo(IDOMKeyboardEvent
*iface
, UINT iTInfo
,
1959 LCID lcid
, ITypeInfo
**ppTInfo
)
1961 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1962 return IDispatchEx_GetTypeInfo(&This
->ui_event
.event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1965 static HRESULT WINAPI
DOMKeyboardEvent_GetIDsOfNames(IDOMKeyboardEvent
*iface
, REFIID riid
,
1966 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1968 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1969 return IDispatchEx_GetIDsOfNames(&This
->ui_event
.event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1973 static HRESULT WINAPI
DOMKeyboardEvent_Invoke(IDOMKeyboardEvent
*iface
, DISPID dispIdMember
,
1974 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1975 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1977 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1978 return IDispatchEx_Invoke(&This
->ui_event
.event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1979 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1982 static HRESULT WINAPI
DOMKeyboardEvent_get_key(IDOMKeyboardEvent
*iface
, BSTR
*p
)
1984 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1988 TRACE("(%p)->(%p)\n", This
, p
);
1991 nsAString_Init(&key_str
, NULL
);
1992 nsres
= nsIDOMKeyEvent_GetKey(This
->nsevent
, &key_str
);
1993 return return_nsstr(nsres
, &key_str
, p
);
1996 static HRESULT WINAPI
DOMKeyboardEvent_get_location(IDOMKeyboardEvent
*iface
, ULONG
*p
)
1998 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2002 TRACE("(%p)->(%p)\n", This
, p
);
2004 nsres
= nsIDOMKeyEvent_GetLocation(This
->nsevent
, &r
);
2005 if(NS_FAILED(nsres
))
2012 static HRESULT WINAPI
DOMKeyboardEvent_get_ctrlKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
2014 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2018 TRACE("(%p)->(%p)\n", This
, p
);
2020 nsres
= nsIDOMKeyEvent_GetCtrlKey(This
->nsevent
, &r
);
2021 if(NS_FAILED(nsres
))
2024 *p
= variant_bool(r
);
2028 static HRESULT WINAPI
DOMKeyboardEvent_get_shiftKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
2030 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2034 TRACE("(%p)->(%p)\n", This
, p
);
2036 nsres
= nsIDOMKeyEvent_GetShiftKey(This
->nsevent
, &r
);
2037 if(NS_FAILED(nsres
))
2040 *p
= variant_bool(r
);
2044 static HRESULT WINAPI
DOMKeyboardEvent_get_altKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
2046 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2050 TRACE("(%p)->(%p)\n", This
, p
);
2052 nsres
= nsIDOMKeyEvent_GetAltKey(This
->nsevent
, &r
);
2053 if(NS_FAILED(nsres
))
2056 *p
= variant_bool(r
);
2060 static HRESULT WINAPI
DOMKeyboardEvent_get_metaKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
2062 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2066 TRACE("(%p)->(%p)\n", This
, p
);
2068 nsres
= nsIDOMKeyEvent_GetMetaKey(This
->nsevent
, &r
);
2069 if(NS_FAILED(nsres
))
2072 *p
= variant_bool(r
);
2076 static HRESULT WINAPI
DOMKeyboardEvent_get_repeat(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
2078 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2082 TRACE("(%p)->(%p)\n", This
, p
);
2084 nsres
= nsIDOMKeyEvent_GetRepeat(This
->nsevent
, &r
);
2085 if(NS_FAILED(nsres
))
2088 *p
= variant_bool(r
);
2092 static HRESULT WINAPI
DOMKeyboardEvent_getModifierState(IDOMKeyboardEvent
*iface
, BSTR key
,
2093 VARIANT_BOOL
*state
)
2095 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2096 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(key
), state
);
2100 static HRESULT WINAPI
DOMKeyboardEvent_initKeyboardEvent(IDOMKeyboardEvent
*iface
, BSTR type
,
2101 VARIANT_BOOL can_bubble
, VARIANT_BOOL cancelable
, IHTMLWindow2
*view
, BSTR key
,
2102 ULONG location
, BSTR modifiers_list
, VARIANT_BOOL repeat
, BSTR locale
)
2104 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2105 FIXME("(%p)->(%s %x %x %p %s %lu %s %x %s)\n", This
, debugstr_w(type
), can_bubble
,
2106 cancelable
, view
, debugstr_w(key
), location
, debugstr_w(modifiers_list
),
2107 repeat
, debugstr_w(locale
));
2111 static HRESULT WINAPI
DOMKeyboardEvent_get_keyCode(IDOMKeyboardEvent
*iface
, LONG
*p
)
2113 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2117 TRACE("(%p)->(%p)\n", This
, p
);
2119 nsres
= nsIDOMKeyEvent_GetKeyCode(This
->nsevent
, &r
);
2120 if(NS_FAILED(nsres
))
2127 static HRESULT WINAPI
DOMKeyboardEvent_get_charCode(IDOMKeyboardEvent
*iface
, LONG
*p
)
2129 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2133 TRACE("(%p)->(%p)\n", This
, p
);
2135 nsres
= nsIDOMKeyEvent_GetKeyCode(This
->nsevent
, &r
);
2136 if(NS_FAILED(nsres
))
2143 static HRESULT WINAPI
DOMKeyboardEvent_get_which(IDOMKeyboardEvent
*iface
, LONG
*p
)
2145 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2149 TRACE("(%p)->(%p)\n", This
, p
);
2151 nsres
= nsIDOMKeyEvent_GetWhich(This
->nsevent
, &r
);
2152 if(NS_FAILED(nsres
))
2159 static HRESULT WINAPI
DOMKeyboardEvent_get_char(IDOMKeyboardEvent
*iface
, VARIANT
*p
)
2161 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2162 FIXME("(%p)->(%p)\n", This
, p
);
2166 static HRESULT WINAPI
DOMKeyboardEvent_get_locale(IDOMKeyboardEvent
*iface
, BSTR
*p
)
2168 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2170 FIXME("(%p)->(%p) semi-stub\n", This
, p
);
2172 *p
= SysAllocString(L
"");
2173 return *p
? S_OK
: E_OUTOFMEMORY
;
2176 static const IDOMKeyboardEventVtbl DOMKeyboardEventVtbl
= {
2177 DOMKeyboardEvent_QueryInterface
,
2178 DOMKeyboardEvent_AddRef
,
2179 DOMKeyboardEvent_Release
,
2180 DOMKeyboardEvent_GetTypeInfoCount
,
2181 DOMKeyboardEvent_GetTypeInfo
,
2182 DOMKeyboardEvent_GetIDsOfNames
,
2183 DOMKeyboardEvent_Invoke
,
2184 DOMKeyboardEvent_get_key
,
2185 DOMKeyboardEvent_get_location
,
2186 DOMKeyboardEvent_get_ctrlKey
,
2187 DOMKeyboardEvent_get_shiftKey
,
2188 DOMKeyboardEvent_get_altKey
,
2189 DOMKeyboardEvent_get_metaKey
,
2190 DOMKeyboardEvent_get_repeat
,
2191 DOMKeyboardEvent_getModifierState
,
2192 DOMKeyboardEvent_initKeyboardEvent
,
2193 DOMKeyboardEvent_get_keyCode
,
2194 DOMKeyboardEvent_get_charCode
,
2195 DOMKeyboardEvent_get_which
,
2196 DOMKeyboardEvent_get_char
,
2197 DOMKeyboardEvent_get_locale
2200 static DOMKeyboardEvent
*DOMKeyboardEvent_from_DOMEvent(DOMEvent
*event
)
2202 return CONTAINING_RECORD(event
, DOMKeyboardEvent
, ui_event
.event
);
2205 static void *DOMKeyboardEvent_query_interface(DOMEvent
*event
, REFIID riid
)
2207 DOMKeyboardEvent
*This
= DOMKeyboardEvent_from_DOMEvent(event
);
2208 if(IsEqualGUID(&IID_IDOMKeyboardEvent
, riid
))
2209 return &This
->IDOMKeyboardEvent_iface
;
2210 if(IsEqualGUID(&IID_IDOMUIEvent
, riid
))
2211 return &This
->ui_event
.IDOMUIEvent_iface
;
2215 static void DOMKeyboardEvent_destroy(DOMEvent
*event
)
2217 DOMKeyboardEvent
*This
= DOMKeyboardEvent_from_DOMEvent(event
);
2218 DOMUIEvent_destroy(&This
->ui_event
.event
);
2219 nsIDOMKeyEvent_Release(This
->nsevent
);
2224 IWinePageTransitionEvent IWinePageTransitionEvent_iface
;
2225 } DOMPageTransitionEvent
;
2227 static inline DOMPageTransitionEvent
*impl_from_IWinePageTransitionEvent(IWinePageTransitionEvent
*iface
)
2229 return CONTAINING_RECORD(iface
, DOMPageTransitionEvent
, IWinePageTransitionEvent_iface
);
2232 static HRESULT WINAPI
DOMPageTransitionEvent_QueryInterface(IWinePageTransitionEvent
*iface
, REFIID riid
, void **ppv
)
2234 DOMPageTransitionEvent
*This
= impl_from_IWinePageTransitionEvent(iface
);
2235 return IDOMEvent_QueryInterface(&This
->event
.IDOMEvent_iface
, riid
, ppv
);
2238 static ULONG WINAPI
DOMPageTransitionEvent_AddRef(IWinePageTransitionEvent
*iface
)
2240 DOMPageTransitionEvent
*This
= impl_from_IWinePageTransitionEvent(iface
);
2241 return IDOMEvent_AddRef(&This
->event
.IDOMEvent_iface
);
2244 static ULONG WINAPI
DOMPageTransitionEvent_Release(IWinePageTransitionEvent
*iface
)
2246 DOMPageTransitionEvent
*This
= impl_from_IWinePageTransitionEvent(iface
);
2247 return IDOMEvent_Release(&This
->event
.IDOMEvent_iface
);
2250 static HRESULT WINAPI
DOMPageTransitionEvent_GetTypeInfoCount(IWinePageTransitionEvent
*iface
, UINT
*pctinfo
)
2252 DOMPageTransitionEvent
*This
= impl_from_IWinePageTransitionEvent(iface
);
2253 return IDispatchEx_GetTypeInfoCount(&This
->event
.dispex
.IDispatchEx_iface
, pctinfo
);
2256 static HRESULT WINAPI
DOMPageTransitionEvent_GetTypeInfo(IWinePageTransitionEvent
*iface
, UINT iTInfo
,
2257 LCID lcid
, ITypeInfo
**ppTInfo
)
2259 DOMPageTransitionEvent
*This
= impl_from_IWinePageTransitionEvent(iface
);
2260 return IDispatchEx_GetTypeInfo(&This
->event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
2263 static HRESULT WINAPI
DOMPageTransitionEvent_GetIDsOfNames(IWinePageTransitionEvent
*iface
, REFIID riid
,
2264 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2266 DOMPageTransitionEvent
*This
= impl_from_IWinePageTransitionEvent(iface
);
2267 return IDispatchEx_GetIDsOfNames(&This
->event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
2271 static HRESULT WINAPI
DOMPageTransitionEvent_Invoke(IWinePageTransitionEvent
*iface
, DISPID dispIdMember
,
2272 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2273 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2275 DOMPageTransitionEvent
*This
= impl_from_IWinePageTransitionEvent(iface
);
2276 return IDispatchEx_Invoke(&This
->event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
2277 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2280 static HRESULT WINAPI
DOMPageTransitionEvent_get_persisted(IWinePageTransitionEvent
*iface
, VARIANT_BOOL
*p
)
2282 DOMPageTransitionEvent
*This
= impl_from_IWinePageTransitionEvent(iface
);
2284 FIXME("(%p)->(%p): always returning FALSE\n", This
, p
);
2290 static const IWinePageTransitionEventVtbl DOMPageTransitionEventVtbl
= {
2291 DOMPageTransitionEvent_QueryInterface
,
2292 DOMPageTransitionEvent_AddRef
,
2293 DOMPageTransitionEvent_Release
,
2294 DOMPageTransitionEvent_GetTypeInfoCount
,
2295 DOMPageTransitionEvent_GetTypeInfo
,
2296 DOMPageTransitionEvent_GetIDsOfNames
,
2297 DOMPageTransitionEvent_Invoke
,
2298 DOMPageTransitionEvent_get_persisted
2301 static DOMPageTransitionEvent
*DOMPageTransitionEvent_from_DOMEvent(DOMEvent
*event
)
2303 return CONTAINING_RECORD(event
, DOMPageTransitionEvent
, event
);
2306 static void *DOMPageTransitionEvent_query_interface(DOMEvent
*event
, REFIID riid
)
2308 DOMPageTransitionEvent
*page_transition_event
= DOMPageTransitionEvent_from_DOMEvent(event
);
2309 if(IsEqualGUID(&IID_IWinePageTransitionEvent
, riid
))
2310 return &page_transition_event
->IWinePageTransitionEvent_iface
;
2316 IDOMCustomEvent IDOMCustomEvent_iface
;
2320 static inline DOMCustomEvent
*impl_from_IDOMCustomEvent(IDOMCustomEvent
*iface
)
2322 return CONTAINING_RECORD(iface
, DOMCustomEvent
, IDOMCustomEvent_iface
);
2325 static HRESULT WINAPI
DOMCustomEvent_QueryInterface(IDOMCustomEvent
*iface
, REFIID riid
, void **ppv
)
2327 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2328 return IDOMEvent_QueryInterface(&This
->event
.IDOMEvent_iface
, riid
, ppv
);
2331 static ULONG WINAPI
DOMCustomEvent_AddRef(IDOMCustomEvent
*iface
)
2333 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2334 return IDOMEvent_AddRef(&This
->event
.IDOMEvent_iface
);
2337 static ULONG WINAPI
DOMCustomEvent_Release(IDOMCustomEvent
*iface
)
2339 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2340 return IDOMEvent_Release(&This
->event
.IDOMEvent_iface
);
2343 static HRESULT WINAPI
DOMCustomEvent_GetTypeInfoCount(IDOMCustomEvent
*iface
, UINT
*pctinfo
)
2345 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2346 return IDispatchEx_GetTypeInfoCount(&This
->event
.dispex
.IDispatchEx_iface
, pctinfo
);
2349 static HRESULT WINAPI
DOMCustomEvent_GetTypeInfo(IDOMCustomEvent
*iface
, UINT iTInfo
,
2350 LCID lcid
, ITypeInfo
**ppTInfo
)
2352 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2353 return IDispatchEx_GetTypeInfo(&This
->event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
2356 static HRESULT WINAPI
DOMCustomEvent_GetIDsOfNames(IDOMCustomEvent
*iface
, REFIID riid
,
2357 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2359 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2360 return IDispatchEx_GetIDsOfNames(&This
->event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
2364 static HRESULT WINAPI
DOMCustomEvent_Invoke(IDOMCustomEvent
*iface
, DISPID dispIdMember
,
2365 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2366 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2368 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2369 return IDispatchEx_Invoke(&This
->event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
2370 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2373 static HRESULT WINAPI
DOMCustomEvent_get_detail(IDOMCustomEvent
*iface
, VARIANT
*p
)
2375 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2377 TRACE("(%p)->(%p)\n", This
, p
);
2380 return VariantCopy(p
, &This
->detail
);
2383 static HRESULT WINAPI
DOMCustomEvent_initCustomEvent(IDOMCustomEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
2384 VARIANT_BOOL cancelable
, VARIANT
*detail
)
2386 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2389 TRACE("(%p)->(%s %x %x %s)\n", This
, debugstr_w(type
), can_bubble
, cancelable
, debugstr_variant(detail
));
2391 hres
= IDOMEvent_initEvent(&This
->event
.IDOMEvent_iface
, type
, can_bubble
, cancelable
);
2395 return VariantCopy(&This
->detail
, detail
);
2398 static const IDOMCustomEventVtbl DOMCustomEventVtbl
= {
2399 DOMCustomEvent_QueryInterface
,
2400 DOMCustomEvent_AddRef
,
2401 DOMCustomEvent_Release
,
2402 DOMCustomEvent_GetTypeInfoCount
,
2403 DOMCustomEvent_GetTypeInfo
,
2404 DOMCustomEvent_GetIDsOfNames
,
2405 DOMCustomEvent_Invoke
,
2406 DOMCustomEvent_get_detail
,
2407 DOMCustomEvent_initCustomEvent
2410 static DOMCustomEvent
*DOMCustomEvent_from_DOMEvent(DOMEvent
*event
)
2412 return CONTAINING_RECORD(event
, DOMCustomEvent
, event
);
2415 static void *DOMCustomEvent_query_interface(DOMEvent
*event
, REFIID riid
)
2417 DOMCustomEvent
*custom_event
= DOMCustomEvent_from_DOMEvent(event
);
2418 if(IsEqualGUID(&IID_IDOMCustomEvent
, riid
))
2419 return &custom_event
->IDOMCustomEvent_iface
;
2423 static void DOMCustomEvent_destroy(DOMEvent
*event
)
2425 DOMCustomEvent
*custom_event
= DOMCustomEvent_from_DOMEvent(event
);
2426 VariantClear(&custom_event
->detail
);
2431 IDOMMessageEvent IDOMMessageEvent_iface
;
2435 static inline DOMMessageEvent
*impl_from_IDOMMessageEvent(IDOMMessageEvent
*iface
)
2437 return CONTAINING_RECORD(iface
, DOMMessageEvent
, IDOMMessageEvent_iface
);
2440 static HRESULT WINAPI
DOMMessageEvent_QueryInterface(IDOMMessageEvent
*iface
, REFIID riid
, void **ppv
)
2442 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2443 return IDOMEvent_QueryInterface(&This
->event
.IDOMEvent_iface
, riid
, ppv
);
2446 static ULONG WINAPI
DOMMessageEvent_AddRef(IDOMMessageEvent
*iface
)
2448 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2449 return IDOMEvent_AddRef(&This
->event
.IDOMEvent_iface
);
2452 static ULONG WINAPI
DOMMessageEvent_Release(IDOMMessageEvent
*iface
)
2454 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2455 return IDOMEvent_Release(&This
->event
.IDOMEvent_iface
);
2458 static HRESULT WINAPI
DOMMessageEvent_GetTypeInfoCount(IDOMMessageEvent
*iface
, UINT
*pctinfo
)
2460 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2461 return IDispatchEx_GetTypeInfoCount(&This
->event
.dispex
.IDispatchEx_iface
, pctinfo
);
2464 static HRESULT WINAPI
DOMMessageEvent_GetTypeInfo(IDOMMessageEvent
*iface
, UINT iTInfo
,
2465 LCID lcid
, ITypeInfo
**ppTInfo
)
2467 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2468 return IDispatchEx_GetTypeInfo(&This
->event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
2471 static HRESULT WINAPI
DOMMessageEvent_GetIDsOfNames(IDOMMessageEvent
*iface
, REFIID riid
,
2472 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2474 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2475 return IDispatchEx_GetIDsOfNames(&This
->event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
2479 static HRESULT WINAPI
DOMMessageEvent_Invoke(IDOMMessageEvent
*iface
, DISPID dispIdMember
,
2480 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2481 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2483 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2484 return IDispatchEx_Invoke(&This
->event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
2485 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2488 static HRESULT WINAPI
DOMMessageEvent_get_data(IDOMMessageEvent
*iface
, BSTR
*p
)
2490 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2492 TRACE("(%p)->(%p)\n", This
, p
);
2494 if(V_VT(&This
->data
) != VT_BSTR
) {
2495 FIXME("non-string data\n");
2499 return (*p
= SysAllocString(V_BSTR(&This
->data
))) ? S_OK
: E_OUTOFMEMORY
;
2502 static HRESULT
DOMMessageEvent_get_data_hook(DispatchEx
*dispex
, WORD flags
, DISPPARAMS
*dp
, VARIANT
*res
,
2503 EXCEPINFO
*ei
, IServiceProvider
*caller
)
2505 DOMMessageEvent
*This
= CONTAINING_RECORD(dispex
, DOMMessageEvent
, event
.dispex
);
2507 if(!(flags
& DISPATCH_PROPERTYGET
) || !res
)
2510 TRACE("(%p)->(%p)\n", This
, res
);
2512 V_VT(res
) = VT_EMPTY
;
2513 return VariantCopy(res
, &This
->data
);
2516 static HRESULT WINAPI
DOMMessageEvent_get_origin(IDOMMessageEvent
*iface
, BSTR
*p
)
2518 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2519 FIXME("(%p)->(%p)\n", This
, p
);
2523 static HRESULT WINAPI
DOMMessageEvent_get_source(IDOMMessageEvent
*iface
, IHTMLWindow2
**p
)
2525 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2526 FIXME("(%p)->(%p)\n", This
, p
);
2530 static HRESULT WINAPI
DOMMessageEvent_initMessageEvent(IDOMMessageEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
2531 VARIANT_BOOL cancelable
, BSTR data
, BSTR origin
,
2532 BSTR last_event_id
, IHTMLWindow2
*source
)
2534 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2535 FIXME("(%p)->(%s %x %x %s %s %s %p)\n", This
, debugstr_w(type
), can_bubble
, cancelable
,
2536 debugstr_w(data
), debugstr_w(origin
), debugstr_w(last_event_id
), source
);
2540 static const IDOMMessageEventVtbl DOMMessageEventVtbl
= {
2541 DOMMessageEvent_QueryInterface
,
2542 DOMMessageEvent_AddRef
,
2543 DOMMessageEvent_Release
,
2544 DOMMessageEvent_GetTypeInfoCount
,
2545 DOMMessageEvent_GetTypeInfo
,
2546 DOMMessageEvent_GetIDsOfNames
,
2547 DOMMessageEvent_Invoke
,
2548 DOMMessageEvent_get_data
,
2549 DOMMessageEvent_get_origin
,
2550 DOMMessageEvent_get_source
,
2551 DOMMessageEvent_initMessageEvent
2554 static DOMMessageEvent
*DOMMessageEvent_from_DOMEvent(DOMEvent
*event
)
2556 return CONTAINING_RECORD(event
, DOMMessageEvent
, event
);
2559 static void *DOMMessageEvent_query_interface(DOMEvent
*event
, REFIID riid
)
2561 DOMMessageEvent
*message_event
= DOMMessageEvent_from_DOMEvent(event
);
2562 if(IsEqualGUID(&IID_IDOMMessageEvent
, riid
))
2563 return &message_event
->IDOMMessageEvent_iface
;
2567 static void DOMMessageEvent_destroy(DOMEvent
*event
)
2569 DOMMessageEvent
*message_event
= DOMMessageEvent_from_DOMEvent(event
);
2570 VariantClear(&message_event
->data
);
2573 static void DOMMessageEvent_init_dispex_info(dispex_data_t
*info
, compat_mode_t compat_mode
)
2575 static const dispex_hook_t hooks
[] = {
2576 {DISPID_IDOMMESSAGEEVENT_DATA
, DOMMessageEvent_get_data_hook
},
2579 dispex_info_add_interface(info
, IDOMMessageEvent_tid
, compat_mode
>= COMPAT_MODE_IE10
? hooks
: NULL
);
2584 IDOMProgressEvent IDOMProgressEvent_iface
;
2585 nsIDOMProgressEvent
*nsevent
;
2589 static inline DOMProgressEvent
*impl_from_IDOMProgressEvent(IDOMProgressEvent
*iface
)
2591 return CONTAINING_RECORD(iface
, DOMProgressEvent
, IDOMProgressEvent_iface
);
2594 static HRESULT WINAPI
DOMProgressEvent_QueryInterface(IDOMProgressEvent
*iface
, REFIID riid
, void **ppv
)
2596 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2597 return IDOMEvent_QueryInterface(&This
->event
.IDOMEvent_iface
, riid
, ppv
);
2600 static ULONG WINAPI
DOMProgressEvent_AddRef(IDOMProgressEvent
*iface
)
2602 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2603 return IDOMEvent_AddRef(&This
->event
.IDOMEvent_iface
);
2606 static ULONG WINAPI
DOMProgressEvent_Release(IDOMProgressEvent
*iface
)
2608 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2609 return IDOMEvent_Release(&This
->event
.IDOMEvent_iface
);
2612 static HRESULT WINAPI
DOMProgressEvent_GetTypeInfoCount(IDOMProgressEvent
*iface
, UINT
*pctinfo
)
2614 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2615 return IDispatchEx_GetTypeInfoCount(&This
->event
.dispex
.IDispatchEx_iface
, pctinfo
);
2618 static HRESULT WINAPI
DOMProgressEvent_GetTypeInfo(IDOMProgressEvent
*iface
, UINT iTInfo
,
2619 LCID lcid
, ITypeInfo
**ppTInfo
)
2621 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2622 return IDispatchEx_GetTypeInfo(&This
->event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
2625 static HRESULT WINAPI
DOMProgressEvent_GetIDsOfNames(IDOMProgressEvent
*iface
, REFIID riid
,
2626 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2628 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2629 return IDispatchEx_GetIDsOfNames(&This
->event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
2633 static HRESULT WINAPI
DOMProgressEvent_Invoke(IDOMProgressEvent
*iface
, DISPID dispIdMember
,
2634 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2635 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2637 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2638 return IDispatchEx_Invoke(&This
->event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
2639 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2642 static HRESULT WINAPI
DOMProgressEvent_get_lengthComputable(IDOMProgressEvent
*iface
, VARIANT_BOOL
*p
)
2644 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2648 TRACE("(%p)->(%p)\n", This
, p
);
2650 nsres
= nsIDOMProgressEvent_GetLengthComputable(This
->nsevent
, &b
);
2651 if(NS_FAILED(nsres
))
2652 return map_nsresult(nsres
);
2654 *p
= b
? VARIANT_TRUE
: VARIANT_FALSE
;
2658 static HRESULT WINAPI
DOMProgressEvent_get_loaded(IDOMProgressEvent
*iface
, ULONGLONG
*p
)
2660 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2662 TRACE("(%p)->(%p)\n", This
, p
);
2664 return map_nsresult(nsIDOMProgressEvent_GetLoaded(This
->nsevent
, p
));
2667 static HRESULT WINAPI
DOMProgressEvent_get_total(IDOMProgressEvent
*iface
, ULONGLONG
*p
)
2669 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2672 TRACE("(%p)->(%p)\n", This
, p
);
2674 if(!This
->manual_init
&& (NS_FAILED(nsIDOMProgressEvent_GetLengthComputable(This
->nsevent
, &b
)) || !b
)) {
2679 return map_nsresult(nsIDOMProgressEvent_GetTotal(This
->nsevent
, p
));
2682 static HRESULT WINAPI
DOMProgressEvent_initProgressEvent(IDOMProgressEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
2683 VARIANT_BOOL cancelable
, VARIANT_BOOL lengthComputable
,
2684 ULONGLONG loaded
, ULONGLONG total
)
2686 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2691 TRACE("(%p)->(%s %x %x %x %s %s)\n", This
, debugstr_w(type
), can_bubble
, cancelable
, lengthComputable
,
2692 wine_dbgstr_longlong(loaded
), wine_dbgstr_longlong(total
));
2694 if(This
->event
.target
) {
2695 TRACE("called on already dispatched event\n");
2699 hres
= IDOMEvent_initEvent(&This
->event
.IDOMEvent_iface
, type
, can_bubble
, cancelable
);
2700 if(SUCCEEDED(hres
)) {
2701 nsAString_InitDepend(&type_str
, type
);
2702 nsres
= nsIDOMProgressEvent_InitProgressEvent(This
->nsevent
, &type_str
, !!can_bubble
, !!cancelable
,
2703 !!lengthComputable
, loaded
, total
);
2704 nsAString_Finish(&type_str
);
2705 if(NS_FAILED(nsres
))
2706 return map_nsresult(nsres
);
2707 This
->manual_init
= TRUE
;
2713 static const IDOMProgressEventVtbl DOMProgressEventVtbl
= {
2714 DOMProgressEvent_QueryInterface
,
2715 DOMProgressEvent_AddRef
,
2716 DOMProgressEvent_Release
,
2717 DOMProgressEvent_GetTypeInfoCount
,
2718 DOMProgressEvent_GetTypeInfo
,
2719 DOMProgressEvent_GetIDsOfNames
,
2720 DOMProgressEvent_Invoke
,
2721 DOMProgressEvent_get_lengthComputable
,
2722 DOMProgressEvent_get_loaded
,
2723 DOMProgressEvent_get_total
,
2724 DOMProgressEvent_initProgressEvent
2727 static DOMProgressEvent
*DOMProgressEvent_from_DOMEvent(DOMEvent
*event
)
2729 return CONTAINING_RECORD(event
, DOMProgressEvent
, event
);
2732 static void *DOMProgressEvent_query_interface(DOMEvent
*event
, REFIID riid
)
2734 DOMProgressEvent
*This
= DOMProgressEvent_from_DOMEvent(event
);
2735 if(IsEqualGUID(&IID_IDOMProgressEvent
, riid
))
2736 return &This
->IDOMProgressEvent_iface
;
2740 static void DOMProgressEvent_destroy(DOMEvent
*event
)
2742 DOMProgressEvent
*This
= DOMProgressEvent_from_DOMEvent(event
);
2743 nsIDOMProgressEvent_Release(This
->nsevent
);
2748 IDOMStorageEvent IDOMStorageEvent_iface
;
2755 static inline DOMStorageEvent
*impl_from_IDOMStorageEvent(IDOMStorageEvent
*iface
)
2757 return CONTAINING_RECORD(iface
, DOMStorageEvent
, IDOMStorageEvent_iface
);
2760 static HRESULT WINAPI
DOMStorageEvent_QueryInterface(IDOMStorageEvent
*iface
, REFIID riid
, void **ppv
)
2762 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2763 return IDOMEvent_QueryInterface(&This
->event
.IDOMEvent_iface
, riid
, ppv
);
2766 static ULONG WINAPI
DOMStorageEvent_AddRef(IDOMStorageEvent
*iface
)
2768 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2769 return IDOMEvent_AddRef(&This
->event
.IDOMEvent_iface
);
2772 static ULONG WINAPI
DOMStorageEvent_Release(IDOMStorageEvent
*iface
)
2774 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2775 return IDOMEvent_Release(&This
->event
.IDOMEvent_iface
);
2778 static HRESULT WINAPI
DOMStorageEvent_GetTypeInfoCount(IDOMStorageEvent
*iface
, UINT
*pctinfo
)
2780 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2781 return IDispatchEx_GetTypeInfoCount(&This
->event
.dispex
.IDispatchEx_iface
, pctinfo
);
2784 static HRESULT WINAPI
DOMStorageEvent_GetTypeInfo(IDOMStorageEvent
*iface
, UINT iTInfo
,
2785 LCID lcid
, ITypeInfo
**ppTInfo
)
2787 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2788 return IDispatchEx_GetTypeInfo(&This
->event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
2791 static HRESULT WINAPI
DOMStorageEvent_GetIDsOfNames(IDOMStorageEvent
*iface
, REFIID riid
,
2792 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2794 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2795 return IDispatchEx_GetIDsOfNames(&This
->event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
2799 static HRESULT WINAPI
DOMStorageEvent_Invoke(IDOMStorageEvent
*iface
, DISPID dispIdMember
,
2800 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2801 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2803 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2804 return IDispatchEx_Invoke(&This
->event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
2805 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2808 static HRESULT WINAPI
DOMStorageEvent_get_key(IDOMStorageEvent
*iface
, BSTR
*p
)
2810 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2812 TRACE("(%p)->(%p)\n", This
, p
);
2815 return (*p
= SysAllocStringLen(This
->key
, SysStringLen(This
->key
))) ? S_OK
: E_OUTOFMEMORY
;
2820 static HRESULT WINAPI
DOMStorageEvent_get_oldValue(IDOMStorageEvent
*iface
, BSTR
*p
)
2822 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2824 TRACE("(%p)->(%p)\n", This
, p
);
2827 return (*p
= SysAllocStringLen(This
->old_value
, SysStringLen(This
->old_value
))) ? S_OK
: E_OUTOFMEMORY
;
2832 static HRESULT WINAPI
DOMStorageEvent_get_newValue(IDOMStorageEvent
*iface
, BSTR
*p
)
2834 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2836 TRACE("(%p)->(%p)\n", This
, p
);
2839 return (*p
= SysAllocStringLen(This
->new_value
, SysStringLen(This
->new_value
))) ? S_OK
: E_OUTOFMEMORY
;
2844 static HRESULT WINAPI
DOMStorageEvent_get_url(IDOMStorageEvent
*iface
, BSTR
*p
)
2846 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2848 TRACE("(%p)->(%p)\n", This
, p
);
2851 return (*p
= SysAllocStringLen(This
->url
, SysStringLen(This
->url
))) ? S_OK
: E_OUTOFMEMORY
;
2856 static HRESULT WINAPI
DOMStorageEvent_get_storageArea(IDOMStorageEvent
*iface
, IHTMLStorage
**p
)
2858 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2859 FIXME("(%p)->(%p)\n", This
, p
);
2863 static HRESULT WINAPI
DOMStorageEvent_initStorageEvent(IDOMStorageEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
2864 VARIANT_BOOL cancelable
, BSTR keyArg
, BSTR oldValueArg
,
2865 BSTR newValueArg
, BSTR urlArg
, IHTMLStorage
*storageAreaArg
)
2867 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2868 FIXME("(%p)->(%s %x %x %s %s %s %s %p)\n", This
, debugstr_w(type
), can_bubble
, cancelable
,
2869 debugstr_w(keyArg
), debugstr_w(oldValueArg
), debugstr_w(newValueArg
), debugstr_w(urlArg
), storageAreaArg
);
2873 static const IDOMStorageEventVtbl DOMStorageEventVtbl
= {
2874 DOMStorageEvent_QueryInterface
,
2875 DOMStorageEvent_AddRef
,
2876 DOMStorageEvent_Release
,
2877 DOMStorageEvent_GetTypeInfoCount
,
2878 DOMStorageEvent_GetTypeInfo
,
2879 DOMStorageEvent_GetIDsOfNames
,
2880 DOMStorageEvent_Invoke
,
2881 DOMStorageEvent_get_key
,
2882 DOMStorageEvent_get_oldValue
,
2883 DOMStorageEvent_get_newValue
,
2884 DOMStorageEvent_get_url
,
2885 DOMStorageEvent_get_storageArea
,
2886 DOMStorageEvent_initStorageEvent
2889 static DOMStorageEvent
*DOMStorageEvent_from_DOMEvent(DOMEvent
*event
)
2891 return CONTAINING_RECORD(event
, DOMStorageEvent
, event
);
2894 static void *DOMStorageEvent_query_interface(DOMEvent
*event
, REFIID riid
)
2896 DOMStorageEvent
*storage_event
= DOMStorageEvent_from_DOMEvent(event
);
2897 if(IsEqualGUID(&IID_IDOMStorageEvent
, riid
))
2898 return &storage_event
->IDOMStorageEvent_iface
;
2902 static void DOMStorageEvent_destroy(DOMEvent
*event
)
2904 DOMStorageEvent
*storage_event
= DOMStorageEvent_from_DOMEvent(event
);
2905 SysFreeString(storage_event
->key
);
2906 SysFreeString(storage_event
->old_value
);
2907 SysFreeString(storage_event
->new_value
);
2908 SysFreeString(storage_event
->url
);
2911 static const tid_t DOMEvent_iface_tids
[] = {
2916 static dispex_static_data_t DOMEvent_dispex
= {
2923 static const tid_t DOMUIEvent_iface_tids
[] = {
2929 static dispex_static_data_t DOMUIEvent_dispex
= {
2933 DOMUIEvent_iface_tids
2936 static const tid_t DOMMouseEvent_iface_tids
[] = {
2943 static dispex_static_data_t DOMMouseEvent_dispex
= {
2946 DispDOMMouseEvent_tid
,
2947 DOMMouseEvent_iface_tids
2950 static const tid_t DOMKeyboardEvent_iface_tids
[] = {
2953 IDOMKeyboardEvent_tid
,
2957 static dispex_static_data_t DOMKeyboardEvent_dispex
= {
2960 DispDOMKeyboardEvent_tid
,
2961 DOMKeyboardEvent_iface_tids
2964 static void DOMPageTransitionEvent_init_dispex_info(dispex_data_t
*info
, compat_mode_t mode
)
2966 if(mode
>= COMPAT_MODE_IE11
)
2967 dispex_info_add_interface(info
, IWinePageTransitionEvent_tid
, NULL
);
2970 dispex_static_data_t DOMPageTransitionEvent_dispex
= {
2971 L
"PageTransitionEvent",
2974 DOMEvent_iface_tids
,
2975 DOMPageTransitionEvent_init_dispex_info
2978 static const tid_t DOMCustomEvent_iface_tids
[] = {
2980 IDOMCustomEvent_tid
,
2984 static dispex_static_data_t DOMCustomEvent_dispex
= {
2987 DispDOMCustomEvent_tid
,
2988 DOMCustomEvent_iface_tids
2991 static const tid_t DOMMessageEvent_iface_tids
[] = {
2996 dispex_static_data_t DOMMessageEvent_dispex
= {
2999 DispDOMMessageEvent_tid
,
3000 DOMMessageEvent_iface_tids
,
3001 DOMMessageEvent_init_dispex_info
3004 static const tid_t DOMProgressEvent_iface_tids
[] = {
3006 IDOMProgressEvent_tid
,
3010 dispex_static_data_t DOMProgressEvent_dispex
= {
3013 DispDOMProgressEvent_tid
,
3014 DOMProgressEvent_iface_tids
3017 static const tid_t DOMStorageEvent_iface_tids
[] = {
3019 IDOMStorageEvent_tid
,
3023 dispex_static_data_t DOMStorageEvent_dispex
= {
3026 DispDOMStorageEvent_tid
,
3027 DOMStorageEvent_iface_tids
3030 static void *event_ctor(unsigned size
, dispex_static_data_t
*dispex_data
, void *(*query_interface
)(DOMEvent
*,REFIID
),
3031 void (*destroy
)(DOMEvent
*), nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3033 DOMEvent
*event
= calloc(1, size
);
3037 event
->IDOMEvent_iface
.lpVtbl
= &DOMEventVtbl
;
3038 event
->query_interface
= query_interface
;
3039 event
->destroy
= destroy
;
3041 event
->event_id
= event_id
;
3042 if(event_id
!= EVENTID_LAST
) {
3043 event
->type
= wcsdup(event_info
[event_id
].name
);
3048 event
->bubbles
= (event_info
[event_id
].flags
& EVENT_BUBBLES
) != 0;
3049 event
->cancelable
= (event_info
[event_id
].flags
& EVENT_CANCELABLE
) != 0;
3051 nsIDOMEvent_AddRef(event
->nsevent
= nsevent
);
3053 event
->time_stamp
= get_time_stamp();
3055 init_dispatch(&event
->dispex
, (IUnknown
*)&event
->IDOMEvent_iface
, dispex_data
, compat_mode
);
3059 static void fill_parent_ui_event(nsIDOMEvent
*nsevent
, DOMUIEvent
*ui_event
)
3061 ui_event
->IDOMUIEvent_iface
.lpVtbl
= &DOMUIEventVtbl
;
3062 nsIDOMEvent_QueryInterface(nsevent
, &IID_nsIDOMUIEvent
, (void**)&ui_event
->nsevent
);
3065 static DOMEvent
*generic_event_ctor(void *iface
, nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3067 return event_ctor(sizeof(DOMEvent
), &DOMEvent_dispex
, NULL
, NULL
, nsevent
, event_id
, compat_mode
);
3070 static DOMEvent
*ui_event_ctor(void *iface
, nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3072 DOMUIEvent
*ui_event
= event_ctor(sizeof(DOMUIEvent
), &DOMUIEvent_dispex
,
3073 DOMUIEvent_query_interface
, DOMUIEvent_destroy
, nsevent
, event_id
, compat_mode
);
3074 if(!ui_event
) return NULL
;
3075 ui_event
->IDOMUIEvent_iface
.lpVtbl
= &DOMUIEventVtbl
;
3076 ui_event
->nsevent
= iface
;
3077 return &ui_event
->event
;
3080 static DOMEvent
*mouse_event_ctor(void *iface
, nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3082 DOMMouseEvent
*mouse_event
= event_ctor(sizeof(DOMMouseEvent
), &DOMMouseEvent_dispex
,
3083 DOMMouseEvent_query_interface
, DOMMouseEvent_destroy
, nsevent
, event_id
, compat_mode
);
3084 if(!mouse_event
) return NULL
;
3085 mouse_event
->IDOMMouseEvent_iface
.lpVtbl
= &DOMMouseEventVtbl
;
3086 mouse_event
->nsevent
= iface
;
3087 fill_parent_ui_event(nsevent
, &mouse_event
->ui_event
);
3088 return &mouse_event
->ui_event
.event
;
3091 static DOMEvent
*keyboard_event_ctor(void *iface
, nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3093 DOMKeyboardEvent
*keyboard_event
= event_ctor(sizeof(DOMKeyboardEvent
), &DOMKeyboardEvent_dispex
,
3094 DOMKeyboardEvent_query_interface
, DOMKeyboardEvent_destroy
, nsevent
, event_id
, compat_mode
);
3095 if(!keyboard_event
) return NULL
;
3096 keyboard_event
->IDOMKeyboardEvent_iface
.lpVtbl
= &DOMKeyboardEventVtbl
;
3097 keyboard_event
->nsevent
= iface
;
3098 fill_parent_ui_event(nsevent
, &keyboard_event
->ui_event
);
3099 return &keyboard_event
->ui_event
.event
;
3102 static DOMEvent
*page_transition_event_ctor(void *iface
, nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3104 DOMPageTransitionEvent
*page_transition_event
= event_ctor(sizeof(DOMCustomEvent
), &DOMPageTransitionEvent_dispex
,
3105 DOMPageTransitionEvent_query_interface
, NULL
, nsevent
, event_id
, compat_mode
);
3106 if(!page_transition_event
) return NULL
;
3107 page_transition_event
->IWinePageTransitionEvent_iface
.lpVtbl
= &DOMPageTransitionEventVtbl
;
3108 return &page_transition_event
->event
;
3111 static DOMEvent
*custom_event_ctor(void *iface
, nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3113 DOMCustomEvent
*custom_event
= event_ctor(sizeof(DOMCustomEvent
), &DOMCustomEvent_dispex
,
3114 DOMCustomEvent_query_interface
, DOMCustomEvent_destroy
, nsevent
, event_id
, compat_mode
);
3115 if(!custom_event
) return NULL
;
3116 custom_event
->IDOMCustomEvent_iface
.lpVtbl
= &DOMCustomEventVtbl
;
3117 nsIDOMCustomEvent_Release(iface
);
3118 return &custom_event
->event
;
3121 static DOMEvent
*progress_event_ctor(void *iface
, nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3123 DOMProgressEvent
*progress_event
;
3125 if(!(progress_event
= event_ctor(sizeof(DOMProgressEvent
), &DOMProgressEvent_dispex
,
3126 DOMProgressEvent_query_interface
, DOMProgressEvent_destroy
, nsevent
, event_id
, compat_mode
)))
3128 progress_event
->IDOMProgressEvent_iface
.lpVtbl
= &DOMProgressEventVtbl
;
3129 progress_event
->nsevent
= iface
;
3130 return &progress_event
->event
;
3133 static DOMEvent
*message_event_ctor(void *iface
, nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3135 DOMMessageEvent
*message_event
= event_ctor(sizeof(DOMMessageEvent
), &DOMMessageEvent_dispex
,
3136 DOMMessageEvent_query_interface
, DOMMessageEvent_destroy
, nsevent
, event_id
, compat_mode
);
3137 if(!message_event
) return NULL
;
3138 message_event
->IDOMMessageEvent_iface
.lpVtbl
= &DOMMessageEventVtbl
;
3139 return &message_event
->event
;
3142 static DOMEvent
*storage_event_ctor(void *iface
, nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3144 DOMStorageEvent
*storage_event
= event_ctor(sizeof(DOMStorageEvent
), &DOMStorageEvent_dispex
,
3145 DOMStorageEvent_query_interface
, DOMStorageEvent_destroy
, nsevent
, event_id
, compat_mode
);
3146 if(!storage_event
) return NULL
;
3147 storage_event
->IDOMStorageEvent_iface
.lpVtbl
= &DOMStorageEventVtbl
;
3148 return &storage_event
->event
;
3151 static const struct {
3153 DOMEvent
*(*ctor
)(void *iface
, nsIDOMEvent
*nsevent
, eventid_t
, compat_mode_t
);
3154 compat_mode_t min_compat_mode
;
3155 } event_types_ctor_table
[] = {
3156 [EVENT_TYPE_EVENT
] = { NULL
, generic_event_ctor
},
3157 [EVENT_TYPE_UIEVENT
] = { &IID_nsIDOMUIEvent
, ui_event_ctor
},
3158 [EVENT_TYPE_MOUSE
] = { &IID_nsIDOMMouseEvent
, mouse_event_ctor
},
3159 [EVENT_TYPE_KEYBOARD
] = { &IID_nsIDOMKeyEvent
, keyboard_event_ctor
},
3160 [EVENT_TYPE_CLIPBOARD
] = { NULL
, generic_event_ctor
},
3161 [EVENT_TYPE_FOCUS
] = { NULL
, generic_event_ctor
},
3162 [EVENT_TYPE_DRAG
] = { NULL
, generic_event_ctor
},
3163 [EVENT_TYPE_PAGETRANSITION
] = { NULL
, page_transition_event_ctor
},
3164 [EVENT_TYPE_CUSTOM
] = { &IID_nsIDOMCustomEvent
, custom_event_ctor
},
3165 [EVENT_TYPE_PROGRESS
] = { &IID_nsIDOMProgressEvent
, progress_event_ctor
, COMPAT_MODE_IE10
},
3166 [EVENT_TYPE_MESSAGE
] = { NULL
, message_event_ctor
},
3167 [EVENT_TYPE_STORAGE
] = { NULL
, storage_event_ctor
},
3170 static DOMEvent
*alloc_event(nsIDOMEvent
*nsevent
, compat_mode_t compat_mode
, event_type_t event_type
,
3176 if(compat_mode
< event_types_ctor_table
[event_type
].min_compat_mode
)
3177 event_type
= EVENT_TYPE_EVENT
;
3179 if(event_types_ctor_table
[event_type
].iid
)
3180 nsIDOMEvent_QueryInterface(nsevent
, event_types_ctor_table
[event_type
].iid
, &iface
);
3182 /* Transfer the iface ownership to the ctor on success */
3183 if(!(event
= event_types_ctor_table
[event_type
].ctor(iface
, nsevent
, event_id
, compat_mode
)) && iface
)
3184 nsISupports_Release(iface
);
3188 HRESULT
create_event_from_nsevent(nsIDOMEvent
*nsevent
, compat_mode_t compat_mode
, DOMEvent
**ret_event
)
3190 event_type_t event_type
= EVENT_TYPE_EVENT
;
3191 eventid_t event_id
= EVENTID_LAST
;
3197 nsAString_Init(&nsstr
, NULL
);
3198 nsres
= nsIDOMEvent_GetType(nsevent
, &nsstr
);
3199 if(NS_SUCCEEDED(nsres
)) {
3201 nsAString_GetData(&nsstr
, &type
);
3202 event_id
= str_to_eid(type
);
3203 if(event_id
== EVENTID_LAST
)
3204 FIXME("unknown event type %s\n", debugstr_w(type
));
3206 ERR("GetType failed: %08lx\n", nsres
);
3208 nsAString_Finish(&nsstr
);
3210 for(i
= 0; i
< ARRAY_SIZE(event_types_ctor_table
); i
++) {
3212 if(event_types_ctor_table
[i
].iid
&&
3213 nsIDOMEvent_QueryInterface(nsevent
, event_types_ctor_table
[i
].iid
, &iface
) == NS_OK
) {
3214 nsISupports_Release(iface
);
3220 event
= alloc_event(nsevent
, compat_mode
, event_type
, event_id
);
3222 return E_OUTOFMEMORY
;
3224 event
->trusted
= TRUE
;
3229 HRESULT
create_document_event_str(HTMLDocumentNode
*doc
, const WCHAR
*type
, IDOMEvent
**ret_event
)
3231 event_type_t event_type
= EVENT_TYPE_EVENT
;
3232 nsIDOMEvent
*nsevent
;
3238 nsAString_InitDepend(&nsstr
, type
);
3239 nsres
= nsIDOMDocument_CreateEvent(doc
->dom_document
, &nsstr
, &nsevent
);
3240 nsAString_Finish(&nsstr
);
3241 if(NS_FAILED(nsres
)) {
3242 FIXME("CreateEvent(%s) failed: %08lx\n", debugstr_w(type
), nsres
);
3246 for(i
= 0; i
< ARRAY_SIZE(event_types
); i
++) {
3247 if(!wcsicmp(type
, event_types
[i
])) {
3253 event
= alloc_event(nsevent
, dispex_compat_mode(&doc
->node
.event_target
.dispex
),
3254 event_type
, EVENTID_LAST
);
3255 nsIDOMEvent_Release(nsevent
);
3257 return E_OUTOFMEMORY
;
3259 *ret_event
= &event
->IDOMEvent_iface
;
3263 HRESULT
create_document_event(HTMLDocumentNode
*doc
, eventid_t event_id
, DOMEvent
**ret_event
)
3265 nsIDOMEvent
*nsevent
;
3270 nsAString_InitDepend(&nsstr
, event_types
[event_info
[event_id
].type
]);
3271 nsres
= nsIDOMDocument_CreateEvent(doc
->dom_document
, &nsstr
, &nsevent
);
3272 nsAString_Finish(&nsstr
);
3273 if(NS_FAILED(nsres
)) {
3274 FIXME("CreateEvent(%s) failed: %08lx\n", debugstr_w(event_types
[event_info
[event_id
].type
]), nsres
);
3278 event
= alloc_event(nsevent
, doc
->document_mode
, event_info
[event_id
].type
, event_id
);
3279 nsIDOMEvent_Release(nsevent
);
3281 return E_OUTOFMEMORY
;
3283 event
->event_id
= event_id
;
3284 event
->trusted
= TRUE
;
3289 HRESULT
create_message_event(HTMLDocumentNode
*doc
, VARIANT
*data
, DOMEvent
**ret
)
3291 DOMMessageEvent
*message_event
;
3295 hres
= create_document_event(doc
, EVENTID_MESSAGE
, &event
);
3298 message_event
= DOMMessageEvent_from_DOMEvent(event
);
3300 V_VT(&message_event
->data
) = VT_EMPTY
;
3301 hres
= VariantCopy(&message_event
->data
, data
);
3303 IDOMEvent_Release(&event
->IDOMEvent_iface
);
3311 HRESULT
create_storage_event(HTMLDocumentNode
*doc
, BSTR key
, BSTR old_value
, BSTR new_value
,
3312 const WCHAR
*url
, BOOL commit
, DOMEvent
**ret
)
3314 DOMStorageEvent
*storage_event
;
3318 hres
= create_document_event(doc
, commit
? EVENTID_STORAGECOMMIT
: EVENTID_STORAGE
, &event
);
3321 storage_event
= DOMStorageEvent_from_DOMEvent(event
);
3324 if((key
&& !(storage_event
->key
= SysAllocString(key
))) ||
3325 (old_value
&& !(storage_event
->old_value
= SysAllocString(old_value
))) ||
3326 (new_value
&& !(storage_event
->new_value
= SysAllocString(new_value
)))) {
3327 IDOMEvent_Release(&event
->IDOMEvent_iface
);
3328 return E_OUTOFMEMORY
;
3332 if(url
&& !(storage_event
->url
= SysAllocString(url
))) {
3333 IDOMEvent_Release(&event
->IDOMEvent_iface
);
3334 return E_OUTOFMEMORY
;
3341 HRESULT
call_disp_func(IDispatch
*disp
, DISPPARAMS
*dp
, VARIANT
*retv
)
3343 IDispatchEx
*dispex
;
3347 memset(&ei
, 0, sizeof(ei
));
3349 hres
= IDispatch_QueryInterface(disp
, &IID_IDispatchEx
, (void**)&dispex
);
3350 if(SUCCEEDED(hres
)) {
3351 hres
= IDispatchEx_InvokeEx(dispex
, 0, GetUserDefaultLCID(), DISPATCH_METHOD
, dp
, retv
, &ei
, NULL
);
3352 IDispatchEx_Release(dispex
);
3354 TRACE("Could not get IDispatchEx interface: %08lx\n", hres
);
3355 hres
= IDispatch_Invoke(disp
, 0, &IID_NULL
, GetUserDefaultLCID(), DISPATCH_METHOD
,
3356 dp
, retv
, &ei
, NULL
);
3362 static HRESULT
call_cp_func(IDispatch
*disp
, DISPID dispid
, IHTMLEventObj
*event_obj
, VARIANT
*retv
)
3364 DISPPARAMS dp
= {NULL
,NULL
,0,0};
3369 TRACE("%p,%ld,%p,%p\n", disp
, dispid
, event_obj
, retv
);
3372 V_VT(&event_arg
) = VT_DISPATCH
;
3373 V_DISPATCH(&event_arg
) = (IDispatch
*)event_obj
;
3374 dp
.rgvarg
= &event_arg
;
3378 memset(&ei
, 0, sizeof(ei
));
3379 return IDispatch_Invoke(disp
, dispid
, &IID_NULL
, 0, DISPATCH_METHOD
, &dp
, retv
, &ei
, &argerr
);
3382 static BOOL
use_event_quirks(EventTarget
*event_target
)
3384 return dispex_compat_mode(&event_target
->dispex
) < COMPAT_MODE_IE9
;
3387 static BOOL
is_cp_event(cp_static_data_t
*data
, DISPID dispid
)
3392 if(!data
|| dispid
== DISPID_UNKNOWN
)
3396 hres
= get_dispids(data
->tid
, &data
->id_cnt
, &data
->ids
);
3402 max
= data
->id_cnt
-1;
3405 if(data
->ids
[i
] == dispid
)
3408 if(data
->ids
[i
] < dispid
)
3417 static void call_event_handlers(EventTarget
*event_target
, DOMEvent
*event
, dispatch_mode_t dispatch_mode
)
3419 const listener_container_t
*container
= get_listener_container(event_target
, event
->type
, FALSE
);
3420 event_listener_t
*listener
, listeners_buf
[8], *listeners
= listeners_buf
;
3421 unsigned listeners_cnt
, listeners_size
;
3422 ConnectionPointContainer
*cp_container
= NULL
;
3423 const event_target_vtbl_t
*vtbl
= NULL
;
3424 BOOL skip_onevent_listener
= FALSE
;
3428 assert(!event
->current_target
);
3429 event
->current_target
= event_target
;
3431 if(container
&& !list_empty(&container
->listeners
) && event
->phase
!= DEP_CAPTURING_PHASE
) {
3432 listener
= LIST_ENTRY(list_tail(&container
->listeners
), event_listener_t
, entry
);
3433 if(listener
&& listener
->function
&& listener
->type
== LISTENER_TYPE_ONEVENT
3434 && use_event_quirks(event_target
)) {
3435 DISPID named_arg
= DISPID_THIS
;
3437 DISPPARAMS dp
= {&arg
, &named_arg
, 1, 1};
3439 skip_onevent_listener
= TRUE
;
3441 V_VT(&arg
) = VT_DISPATCH
;
3442 V_DISPATCH(&arg
) = (IDispatch
*)&event_target
->dispex
.IDispatchEx_iface
;
3443 V_VT(&v
) = VT_EMPTY
;
3445 TRACE("%p %s >>>\n", event_target
, debugstr_w(event
->type
));
3446 hres
= call_disp_func(listener
->function
, &dp
, &v
);
3448 TRACE("%p %s <<< %s\n", event_target
, debugstr_w(event
->type
), debugstr_variant(&v
));
3450 if(event
->cancelable
) {
3451 if(V_VT(&v
) == VT_BOOL
) {
3453 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
3454 }else if(V_VT(&v
) != VT_EMPTY
) {
3455 FIXME("unhandled result %s\n", debugstr_variant(&v
));
3460 WARN("%p %s <<< %08lx\n", event_target
, debugstr_w(event
->type
), hres
);
3466 listeners_size
= ARRAY_SIZE(listeners_buf
);
3469 LIST_FOR_EACH_ENTRY(listener
, &container
->listeners
, event_listener_t
, entry
) {
3470 if(!listener
->function
)
3472 switch(listener
->type
) {
3473 case LISTENER_TYPE_ONEVENT
:
3474 if(skip_onevent_listener
|| event
->phase
== DEP_CAPTURING_PHASE
)
3477 case LISTENER_TYPE_CAPTURE
:
3478 if(event
->phase
== DEP_BUBBLING_PHASE
|| dispatch_mode
== DISPATCH_LEGACY
)
3481 case LISTENER_TYPE_BUBBLE
:
3482 if(event
->phase
== DEP_CAPTURING_PHASE
|| dispatch_mode
== DISPATCH_LEGACY
)
3485 case LISTENER_TYPE_ATTACHED
:
3486 if(event
->phase
== DEP_CAPTURING_PHASE
|| dispatch_mode
== DISPATCH_STANDARD
)
3491 if(listeners_cnt
== listeners_size
) {
3492 event_listener_t
*new_listeners
;
3493 if(listeners
== listeners_buf
) {
3494 new_listeners
= malloc(listeners_size
* 2 * sizeof(*new_listeners
));
3497 memcpy(new_listeners
, listeners
, listeners_cnt
* sizeof(*listeners
));
3499 new_listeners
= realloc(listeners
, listeners_size
* 2 * sizeof(*new_listeners
));
3501 listeners
= new_listeners
;
3502 listeners_size
*= 2;
3505 listeners
[listeners_cnt
].type
= listener
->type
;
3506 IDispatch_AddRef(listeners
[listeners_cnt
].function
= listener
->function
);
3511 for(listener
= listeners
; !event
->stop_immediate_propagation
3512 && listener
< listeners
+ listeners_cnt
; listener
++) {
3513 if(listener
->type
!= LISTENER_TYPE_ATTACHED
) {
3514 DISPID named_arg
= DISPID_THIS
;
3516 DISPPARAMS dp
= {args
, &named_arg
, 2, 1};
3518 V_VT(args
) = VT_DISPATCH
;
3519 V_DISPATCH(args
) = (IDispatch
*)&event_target
->dispex
.IDispatchEx_iface
;
3520 V_VT(args
+1) = VT_DISPATCH
;
3521 V_DISPATCH(args
+1) = dispatch_mode
== DISPATCH_LEGACY
3522 ? (IDispatch
*)event
->event_obj
: (IDispatch
*)&event
->IDOMEvent_iface
;
3523 V_VT(&v
) = VT_EMPTY
;
3525 TRACE("%p %s >>>\n", event_target
, debugstr_w(event
->type
));
3526 hres
= call_disp_func(listener
->function
, &dp
, &v
);
3528 TRACE("%p %s <<< %s\n", event_target
, debugstr_w(event
->type
),
3529 debugstr_variant(&v
));
3531 if(event
->cancelable
) {
3532 if(V_VT(&v
) == VT_BOOL
) {
3534 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
3535 }else if(V_VT(&v
) != VT_EMPTY
) {
3536 FIXME("unhandled result %s\n", debugstr_variant(&v
));
3541 WARN("%p %s <<< %08lx\n", event_target
, debugstr_w(event
->type
), hres
);
3545 DISPPARAMS dp
= {&arg
, NULL
, 1, 0};
3547 V_VT(&arg
) = VT_DISPATCH
;
3548 V_DISPATCH(&arg
) = (IDispatch
*)event
->event_obj
;
3549 V_VT(&v
) = VT_EMPTY
;
3551 TRACE("%p %s attached >>>\n", event_target
, debugstr_w(event
->type
));
3552 hres
= call_disp_func(listener
->function
, &dp
, &v
);
3554 TRACE("%p %s attached <<<\n", event_target
, debugstr_w(event
->type
));
3556 if(event
->cancelable
) {
3557 if(V_VT(&v
) == VT_BOOL
) {
3559 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
3560 }else if(V_VT(&v
) != VT_EMPTY
) {
3561 FIXME("unhandled result %s\n", debugstr_variant(&v
));
3566 WARN("%p %s attached <<< %08lx\n", event_target
, debugstr_w(event
->type
), hres
);
3571 for(listener
= listeners
; listener
< listeners
+ listeners_cnt
; listener
++)
3572 IDispatch_Release(listener
->function
);
3573 if(listeners
!= listeners_buf
)
3576 if(event
->phase
!= DEP_CAPTURING_PHASE
&& event_info
[event
->event_id
].dispid
3577 && (vtbl
= dispex_get_vtbl(&event_target
->dispex
)) && vtbl
->get_cp_container
)
3578 cp_container
= vtbl
->get_cp_container(&event_target
->dispex
);
3580 if(cp_container
->cps
) {
3581 ConnectionPoint
*cp
;
3584 for(j
=0; cp_container
->cp_entries
[j
].riid
; j
++) {
3585 cp
= cp_container
->cps
+ j
;
3586 if(!cp
->sinks_size
|| !is_cp_event(cp
->data
, event_info
[event
->event_id
].dispid
))
3589 for(i
=0; i
< cp
->sinks_size
; i
++) {
3590 if(!cp
->sinks
[i
].disp
)
3593 V_VT(&v
) = VT_EMPTY
;
3595 TRACE("%p cp %s [%u] >>>\n", event_target
, debugstr_w(event
->type
), i
);
3596 hres
= call_cp_func(cp
->sinks
[i
].disp
, event_info
[event
->event_id
].dispid
,
3597 cp
->data
->pass_event_arg
? event
->event_obj
: NULL
, &v
);
3599 TRACE("%p cp %s [%u] <<<\n", event_target
, debugstr_w(event
->type
), i
);
3601 if(event
->cancelable
) {
3602 if(V_VT(&v
) == VT_BOOL
) {
3604 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
3605 }else if(V_VT(&v
) != VT_EMPTY
) {
3606 FIXME("unhandled result %s\n", debugstr_variant(&v
));
3611 WARN("%p cp %s [%u] <<< %08lx\n", event_target
, debugstr_w(event
->type
), i
, hres
);
3616 IConnectionPointContainer_Release(&cp_container
->IConnectionPointContainer_iface
);
3619 event
->current_target
= NULL
;
3622 static HRESULT
dispatch_event_object(EventTarget
*event_target
, DOMEvent
*event
,
3623 dispatch_mode_t dispatch_mode
, VARIANT_BOOL
*r
)
3625 EventTarget
*target_chain_buf
[8], **target_chain
= target_chain_buf
;
3626 unsigned chain_cnt
, chain_buf_size
, i
;
3627 const event_target_vtbl_t
*vtbl
, *target_vtbl
;
3628 HTMLEventObj
*event_obj_ref
= NULL
;
3629 IHTMLEventObj
*prev_event
= NULL
;
3633 TRACE("(%p) %s\n", event_target
, debugstr_w(event
->type
));
3636 FIXME("Uninitialized event.\n");
3640 if(event
->current_target
) {
3641 FIXME("event is being dispatched.\n");
3645 iter
= event_target
;
3646 IEventTarget_AddRef(&event_target
->IEventTarget_iface
);
3649 chain_buf_size
= ARRAY_SIZE(target_chain_buf
);
3652 if(chain_cnt
== chain_buf_size
) {
3653 EventTarget
**new_chain
;
3654 if(target_chain
== target_chain_buf
) {
3655 new_chain
= malloc(chain_buf_size
* 2 * sizeof(*new_chain
));
3658 memcpy(new_chain
, target_chain
, chain_buf_size
* sizeof(*new_chain
));
3660 new_chain
= realloc(target_chain
, chain_buf_size
* 2 * sizeof(*new_chain
));
3664 chain_buf_size
*= 2;
3665 target_chain
= new_chain
;
3668 target_chain
[chain_cnt
++] = iter
;
3670 if(!(vtbl
= dispex_get_vtbl(&iter
->dispex
)) || !vtbl
->get_parent_event_target
)
3672 iter
= vtbl
->get_parent_event_target(&iter
->dispex
);
3675 if(!event
->event_obj
&& !event
->no_event_obj
) {
3676 event_obj_ref
= alloc_event_obj(event
, dispex_compat_mode(&event
->dispex
));
3678 event
->event_obj
= &event_obj_ref
->IHTMLEventObj_iface
;
3681 target_vtbl
= dispex_get_vtbl(&event_target
->dispex
);
3682 if(target_vtbl
&& target_vtbl
->set_current_event
)
3683 prev_event
= target_vtbl
->set_current_event(&event_target
->dispex
, event
->event_obj
);
3686 IEventTarget_Release(&event
->target
->IEventTarget_iface
);
3687 event
->target
= event_target
;
3688 IEventTarget_AddRef(&event_target
->IEventTarget_iface
);
3690 event
->phase
= DEP_CAPTURING_PHASE
;
3692 while(!event
->stop_propagation
&& i
)
3693 call_event_handlers(target_chain
[i
--], event
, dispatch_mode
);
3695 if(!event
->stop_propagation
) {
3696 event
->phase
= DEP_AT_TARGET
;
3697 call_event_handlers(target_chain
[0], event
, dispatch_mode
);
3700 if(event
->bubbles
) {
3701 event
->phase
= DEP_BUBBLING_PHASE
;
3702 for(i
= 1; !event
->stop_propagation
&& i
< chain_cnt
; i
++)
3703 call_event_handlers(target_chain
[i
], event
, dispatch_mode
);
3707 *r
= variant_bool(!event
->prevent_default
);
3709 if(target_vtbl
&& target_vtbl
->set_current_event
) {
3710 IHTMLEventObj
*prev
= target_vtbl
->set_current_event(&event_target
->dispex
, prev_event
);
3712 IHTMLEventObj_Release(prev
);
3716 IHTMLEventObj_Release(prev_event
);
3718 if(event_info
[event
->event_id
].flags
& EVENT_HASDEFAULTHANDLERS
) {
3719 BOOL prevent_default
= event
->prevent_default
;
3720 for(i
= 0; !prevent_default
&& i
< chain_cnt
; i
++) {
3721 vtbl
= dispex_get_vtbl(&target_chain
[i
]->dispex
);
3722 if(!vtbl
|| !vtbl
->handle_event_default
)
3724 hres
= vtbl
->handle_event_default(&event_target
->dispex
, event
->event_id
,
3725 event
->nsevent
, &prevent_default
);
3726 if(FAILED(hres
) || event
->stop_propagation
)
3729 nsIDOMEvent_PreventDefault(event
->nsevent
);
3733 event
->prevent_default
= FALSE
;
3735 event
->event_obj
= NULL
;
3736 IHTMLEventObj_Release(&event_obj_ref
->IHTMLEventObj_iface
);
3739 for(i
= 0; i
< chain_cnt
; i
++)
3740 IEventTarget_Release(&target_chain
[i
]->IEventTarget_iface
);
3741 if(target_chain
!= target_chain_buf
)
3747 void dispatch_event(EventTarget
*event_target
, DOMEvent
*event
)
3749 dispatch_event_object(event_target
, event
, DISPATCH_BOTH
, NULL
);
3752 * We may have registered multiple Gecko listeners for the same event type,
3753 * but we already dispatched event to all relevant targets. Stop event
3754 * propagation here to avoid events being dispatched multiple times.
3756 if(event_info
[event
->event_id
].flags
& EVENT_BIND_TO_TARGET
)
3757 nsIDOMEvent_StopPropagation(event
->nsevent
);
3760 HRESULT
fire_event(HTMLDOMNode
*node
, const WCHAR
*event_name
, VARIANT
*event_var
, VARIANT_BOOL
*cancelled
)
3762 HTMLEventObj
*event_obj
= NULL
;
3764 HRESULT hres
= S_OK
;
3766 eid
= attr_to_eid(event_name
);
3767 if(eid
== EVENTID_LAST
) {
3768 WARN("unknown event %s\n", debugstr_w(event_name
));
3769 return E_INVALIDARG
;
3772 if(event_var
&& V_VT(event_var
) != VT_EMPTY
&& V_VT(event_var
) != VT_ERROR
) {
3773 if(V_VT(event_var
) != VT_DISPATCH
) {
3774 FIXME("event_var %s not supported\n", debugstr_variant(event_var
));
3778 if(V_DISPATCH(event_var
)) {
3779 IHTMLEventObj
*event_iface
;
3781 hres
= IDispatch_QueryInterface(V_DISPATCH(event_var
), &IID_IHTMLEventObj
, (void**)&event_iface
);
3783 FIXME("No IHTMLEventObj iface\n");
3787 event_obj
= unsafe_impl_from_IHTMLEventObj(event_iface
);
3789 ERR("Not our IHTMLEventObj?\n");
3790 IHTMLEventObj_Release(event_iface
);
3797 event_obj
= alloc_event_obj(NULL
, dispex_compat_mode(&node
->event_target
.dispex
));
3799 return E_OUTOFMEMORY
;
3802 if(!event_obj
->event
)
3803 hres
= create_document_event(node
->doc
, eid
, &event_obj
->event
);
3805 if(SUCCEEDED(hres
)) {
3806 event_obj
->event
->event_obj
= &event_obj
->IHTMLEventObj_iface
;
3807 dispatch_event_object(&node
->event_target
, event_obj
->event
, DISPATCH_LEGACY
, NULL
);
3808 event_obj
->event
->event_obj
= NULL
;
3811 IHTMLEventObj_Release(&event_obj
->IHTMLEventObj_iface
);
3815 *cancelled
= VARIANT_TRUE
; /* FIXME */
3819 HRESULT
ensure_doc_nsevent_handler(HTMLDocumentNode
*doc
, nsIDOMNode
*nsnode
, eventid_t eid
)
3821 TRACE("%s\n", debugstr_w(event_info
[eid
].name
));
3823 if(!doc
->dom_document
)
3827 case EVENTID_FOCUSIN
:
3828 doc
->event_vector
[eid
] = TRUE
;
3829 eid
= EVENTID_FOCUS
;
3831 case EVENTID_FOCUSOUT
:
3832 doc
->event_vector
[eid
] = TRUE
;
3839 if(event_info
[eid
].flags
& EVENT_DEFAULTLISTENER
) {
3841 }else if(!(event_info
[eid
].flags
& EVENT_BIND_TO_TARGET
)) {
3845 if(!nsnode
|| nsnode
== doc
->node
.nsnode
) {
3846 if(doc
->event_vector
[eid
])
3848 doc
->event_vector
[eid
] = TRUE
;
3851 add_nsevent_listener(doc
, nsnode
, event_info
[eid
].name
);
3855 void detach_events(HTMLDocumentNode
*doc
)
3857 if(doc
->event_vector
) {
3860 for(i
=0; i
< EVENTID_LAST
; i
++) {
3861 if(doc
->event_vector
[i
]) {
3862 detach_nsevent(doc
, event_info
[i
].name
);
3863 doc
->event_vector
[i
] = FALSE
;
3868 release_nsevents(doc
);
3871 static HRESULT
get_event_dispex_ref(EventTarget
*event_target
, eventid_t eid
, BOOL alloc
, VARIANT
**ret
)
3876 lstrcpyW(buf
+2, event_info
[eid
].name
);
3877 return dispex_get_dprop_ref(&event_target
->dispex
, buf
, alloc
, ret
);
3880 static event_listener_t
*get_onevent_listener(EventTarget
*event_target
, eventid_t eid
, BOOL alloc
)
3882 listener_container_t
*container
;
3883 event_listener_t
*listener
;
3885 container
= get_listener_container(event_target
, event_info
[eid
].name
, alloc
);
3889 LIST_FOR_EACH_ENTRY_REV(listener
, &container
->listeners
, event_listener_t
, entry
) {
3890 if(listener
->type
== LISTENER_TYPE_ONEVENT
)
3897 listener
= malloc(sizeof(*listener
));
3901 listener
->type
= LISTENER_TYPE_ONEVENT
;
3902 listener
->function
= NULL
;
3903 list_add_tail(&container
->listeners
, &listener
->entry
);
3907 static void remove_event_handler(EventTarget
*event_target
, eventid_t eid
)
3909 event_listener_t
*listener
;
3913 hres
= get_event_dispex_ref(event_target
, eid
, FALSE
, &store
);
3915 VariantClear(store
);
3917 listener
= get_onevent_listener(event_target
, eid
, FALSE
);
3918 if(listener
&& listener
->function
) {
3919 IDispatch_Release(listener
->function
);
3920 listener
->function
= NULL
;
3924 static HRESULT
set_event_handler_disp(EventTarget
*event_target
, eventid_t eid
, IDispatch
*disp
)
3926 event_listener_t
*listener
;
3928 if(event_info
[eid
].flags
& EVENT_FIXME
)
3929 FIXME("unimplemented event %s\n", debugstr_w(event_info
[eid
].name
));
3931 remove_event_handler(event_target
, eid
);
3935 listener
= get_onevent_listener(event_target
, eid
, TRUE
);
3937 return E_OUTOFMEMORY
;
3939 if(listener
->function
)
3940 IDispatch_Release(listener
->function
);
3942 IDispatch_AddRef(listener
->function
= disp
);
3946 HRESULT
set_event_handler(EventTarget
*event_target
, eventid_t eid
, VARIANT
*var
)
3950 if(use_event_quirks(event_target
)) {
3951 WARN("attempt to set to VT_EMPTY in quirks mode\n");
3956 remove_event_handler(event_target
, eid
);
3960 return set_event_handler_disp(event_target
, eid
, V_DISPATCH(var
));
3966 if(!use_event_quirks(event_target
))
3967 FIXME("Setting to string %s not supported\n", debugstr_w(V_BSTR(var
)));
3970 * Setting event handler to string is a rare case and we don't want to
3971 * complicate nor increase memory of listener_container_t for that. Instead,
3972 * we store the value in DispatchEx, which can already handle custom
3975 remove_event_handler(event_target
, eid
);
3977 hres
= get_event_dispex_ref(event_target
, eid
, TRUE
, &v
);
3981 V_BSTR(v
) = SysAllocString(V_BSTR(var
));
3983 return E_OUTOFMEMORY
;
3989 FIXME("not handler %s\n", debugstr_variant(var
));
3996 HRESULT
get_event_handler(EventTarget
*event_target
, eventid_t eid
, VARIANT
*var
)
3998 event_listener_t
*listener
;
4002 hres
= get_event_dispex_ref(event_target
, eid
, FALSE
, &v
);
4003 if(SUCCEEDED(hres
) && V_VT(v
) != VT_EMPTY
) {
4004 V_VT(var
) = VT_EMPTY
;
4005 return VariantCopy(var
, v
);
4008 listener
= get_onevent_listener(event_target
, eid
, FALSE
);
4009 if(listener
&& listener
->function
) {
4010 V_VT(var
) = VT_DISPATCH
;
4011 V_DISPATCH(var
) = listener
->function
;
4012 IDispatch_AddRef(V_DISPATCH(var
));
4014 V_VT(var
) = VT_NULL
;
4020 HRESULT
attach_event(EventTarget
*event_target
, BSTR name
, IDispatch
*disp
, VARIANT_BOOL
*res
)
4022 listener_container_t
*container
;
4023 event_listener_t
*listener
;
4027 *res
= VARIANT_FALSE
;
4031 eid
= attr_to_eid(name
);
4032 if(eid
== EVENTID_LAST
) {
4033 WARN("Unknown event\n");
4034 *res
= VARIANT_TRUE
;
4038 container
= get_listener_container(event_target
, event_info
[eid
].name
, TRUE
);
4040 return E_OUTOFMEMORY
;
4042 listener
= malloc(sizeof(*listener
));
4044 return E_OUTOFMEMORY
;
4046 listener
->type
= LISTENER_TYPE_ATTACHED
;
4047 IDispatch_AddRef(listener
->function
= disp
);
4048 if(use_event_quirks(event_target
))
4049 list_add_head(&container
->listeners
, &listener
->entry
);
4051 list_add_tail(&container
->listeners
, &listener
->entry
);
4053 *res
= VARIANT_TRUE
;
4057 HRESULT
detach_event(EventTarget
*event_target
, BSTR name
, IDispatch
*disp
)
4061 eid
= attr_to_eid(name
);
4062 if(eid
== EVENTID_LAST
) {
4063 WARN("Unknown event\n");
4067 remove_event_listener(event_target
, event_info
[eid
].name
, LISTENER_TYPE_ATTACHED
, disp
);
4071 void bind_target_event(HTMLDocumentNode
*doc
, EventTarget
*event_target
, const WCHAR
*event
, IDispatch
*disp
)
4075 TRACE("(%p %p %s %p)\n", doc
, event_target
, debugstr_w(event
), disp
);
4077 eid
= attr_to_eid(event
);
4078 if(eid
== EVENTID_LAST
) {
4079 WARN("Unsupported event %s\n", debugstr_w(event
));
4083 set_event_handler_disp(event_target
, eid
, disp
);
4086 void update_doc_cp_events(HTMLDocumentNode
*doc
, cp_static_data_t
*cp
)
4090 for(i
=0; i
< EVENTID_LAST
; i
++) {
4091 if((event_info
[i
].flags
& EVENT_DEFAULTLISTENER
) && is_cp_event(cp
, event_info
[i
].dispid
))
4092 ensure_doc_nsevent_handler(doc
, NULL
, i
);
4096 void check_event_attr(HTMLDocumentNode
*doc
, nsIDOMElement
*nselem
)
4098 nsIDOMMozNamedAttrMap
*attr_map
;
4099 const PRUnichar
*name
, *value
;
4100 nsAString name_str
, value_str
;
4101 HTMLDOMNode
*node
= NULL
;
4110 nsres
= nsIDOMElement_HasAttributes(nselem
, &has_attrs
);
4111 if(NS_FAILED(nsres
) || !has_attrs
)
4114 nsres
= nsIDOMElement_GetAttributes(nselem
, &attr_map
);
4115 if(NS_FAILED(nsres
))
4118 nsres
= nsIDOMMozNamedAttrMap_GetLength(attr_map
, &length
);
4119 assert(nsres
== NS_OK
);
4121 nsAString_Init(&name_str
, NULL
);
4122 nsAString_Init(&value_str
, NULL
);
4124 for(i
= 0; i
< length
; i
++) {
4125 nsres
= nsIDOMMozNamedAttrMap_Item(attr_map
, i
, &attr
);
4126 if(NS_FAILED(nsres
))
4129 nsres
= nsIDOMAttr_GetName(attr
, &name_str
);
4130 if(NS_FAILED(nsres
)) {
4131 nsIDOMAttr_Release(attr
);
4135 nsAString_GetData(&name_str
, &name
);
4136 eid
= attr_to_eid(name
);
4137 if(eid
== EVENTID_LAST
) {
4138 nsIDOMAttr_Release(attr
);
4142 nsres
= nsIDOMAttr_GetValue(attr
, &value_str
);
4143 nsIDOMAttr_Release(attr
);
4144 if(NS_FAILED(nsres
))
4147 nsAString_GetData(&value_str
, &value
);
4151 TRACE("%p.%s = %s\n", nselem
, debugstr_w(name
), debugstr_w(value
));
4153 disp
= script_parse_event(doc
->window
, value
);
4158 hres
= get_node((nsIDOMNode
*)nselem
, TRUE
, &node
);
4160 IDispatch_Release(disp
);
4165 set_event_handler_disp(get_node_event_prop_target(node
, eid
), eid
, disp
);
4166 IDispatch_Release(disp
);
4171 nsAString_Finish(&name_str
);
4172 nsAString_Finish(&value_str
);
4173 nsIDOMMozNamedAttrMap_Release(attr_map
);
4176 HRESULT
doc_init_events(HTMLDocumentNode
*doc
)
4181 doc
->event_vector
= calloc(EVENTID_LAST
, sizeof(BOOL
));
4182 if(!doc
->event_vector
)
4183 return E_OUTOFMEMORY
;
4187 for(i
=0; i
< EVENTID_LAST
; i
++) {
4188 if(event_info
[i
].flags
& EVENT_HASDEFAULTHANDLERS
) {
4189 hres
= ensure_doc_nsevent_handler(doc
, NULL
, i
);
4198 static inline EventTarget
*impl_from_IEventTarget(IEventTarget
*iface
)
4200 return CONTAINING_RECORD(iface
, EventTarget
, IEventTarget_iface
);
4203 static HRESULT WINAPI
EventTarget_QueryInterface(IEventTarget
*iface
, REFIID riid
, void **ppv
)
4205 EventTarget
*This
= impl_from_IEventTarget(iface
);
4206 return IDispatchEx_QueryInterface(&This
->dispex
.IDispatchEx_iface
, riid
, ppv
);
4209 static ULONG WINAPI
EventTarget_AddRef(IEventTarget
*iface
)
4211 EventTarget
*This
= impl_from_IEventTarget(iface
);
4212 return IDispatchEx_AddRef(&This
->dispex
.IDispatchEx_iface
);
4215 static ULONG WINAPI
EventTarget_Release(IEventTarget
*iface
)
4217 EventTarget
*This
= impl_from_IEventTarget(iface
);
4218 return IDispatchEx_Release(&This
->dispex
.IDispatchEx_iface
);
4221 static HRESULT WINAPI
EventTarget_GetTypeInfoCount(IEventTarget
*iface
, UINT
*pctinfo
)
4223 EventTarget
*This
= impl_from_IEventTarget(iface
);
4224 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
4227 static HRESULT WINAPI
EventTarget_GetTypeInfo(IEventTarget
*iface
, UINT iTInfo
,
4228 LCID lcid
, ITypeInfo
**ppTInfo
)
4230 EventTarget
*This
= impl_from_IEventTarget(iface
);
4231 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
4234 static HRESULT WINAPI
EventTarget_GetIDsOfNames(IEventTarget
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
4235 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
4237 EventTarget
*This
= impl_from_IEventTarget(iface
);
4238 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
,
4239 rgszNames
, cNames
, lcid
, rgDispId
);
4242 static HRESULT WINAPI
EventTarget_Invoke(IEventTarget
*iface
, DISPID dispIdMember
,
4243 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
4244 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
4246 EventTarget
*This
= impl_from_IEventTarget(iface
);
4247 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
,
4248 riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
4251 static HRESULT WINAPI
EventTarget_addEventListener(IEventTarget
*iface
, BSTR type
,
4252 IDispatch
*function
, VARIANT_BOOL capture
)
4254 EventTarget
*This
= impl_from_IEventTarget(iface
);
4255 listener_type_t listener_type
= capture
? LISTENER_TYPE_CAPTURE
: LISTENER_TYPE_BUBBLE
;
4256 listener_container_t
*container
;
4257 event_listener_t
*listener
;
4259 TRACE("(%p)->(%s %p %x)\n", This
, debugstr_w(type
), function
, capture
);
4264 container
= get_listener_container(This
, type
, TRUE
);
4266 return E_OUTOFMEMORY
;
4268 /* check for duplicates */
4269 LIST_FOR_EACH_ENTRY(listener
, &container
->listeners
, event_listener_t
, entry
) {
4270 if(listener
->type
== listener_type
&& listener
->function
== function
)
4274 listener
= malloc(sizeof(*listener
));
4276 return E_OUTOFMEMORY
;
4278 listener
->type
= listener_type
;
4279 IDispatch_AddRef(listener
->function
= function
);
4280 list_add_tail(&container
->listeners
, &listener
->entry
);
4284 static HRESULT WINAPI
EventTarget_removeEventListener(IEventTarget
*iface
, BSTR type
,
4285 IDispatch
*listener
, VARIANT_BOOL capture
)
4287 EventTarget
*This
= impl_from_IEventTarget(iface
);
4289 TRACE("(%p)->(%s %p %x)\n", This
, debugstr_w(type
), listener
, capture
);
4291 remove_event_listener(This
, type
, capture
? LISTENER_TYPE_CAPTURE
: LISTENER_TYPE_BUBBLE
, listener
);
4295 static HRESULT WINAPI
EventTarget_dispatchEvent(IEventTarget
*iface
, IDOMEvent
*event_iface
, VARIANT_BOOL
*result
)
4297 EventTarget
*This
= impl_from_IEventTarget(iface
);
4298 DOMEvent
*event
= unsafe_impl_from_IDOMEvent(event_iface
);
4300 TRACE("(%p)->(%p %p)\n", This
, event
, result
);
4303 WARN("Invalid event\n");
4304 return E_INVALIDARG
;
4307 return dispatch_event_object(This
, event
, DISPATCH_STANDARD
, result
);
4310 static HRESULT
IEventTarget_addEventListener_hook(DispatchEx
*dispex
, WORD flags
,
4311 DISPPARAMS
*dp
, VARIANT
*res
, EXCEPINFO
*ei
, IServiceProvider
*caller
)
4313 /* If only two arguments were given, implicitly set capture to false */
4314 if((flags
& DISPATCH_METHOD
) && dp
->cArgs
== 2 && !dp
->cNamedArgs
) {
4316 DISPPARAMS new_dp
= {args
, NULL
, 3, 0};
4317 V_VT(args
) = VT_BOOL
;
4318 V_BOOL(args
) = VARIANT_FALSE
;
4319 args
[1] = dp
->rgvarg
[0];
4320 args
[2] = dp
->rgvarg
[1];
4322 TRACE("implicit capture\n");
4324 return dispex_call_builtin(dispex
, DISPID_IEVENTTARGET_ADDEVENTLISTENER
, &new_dp
, res
, ei
, caller
);
4327 return S_FALSE
; /* fallback to default */
4330 static HRESULT
IEventTarget_removeEventListener_hook(DispatchEx
*dispex
, WORD flags
,
4331 DISPPARAMS
*dp
, VARIANT
*res
, EXCEPINFO
*ei
, IServiceProvider
*caller
)
4333 /* If only two arguments were given, implicitly set capture to false */
4334 if((flags
& DISPATCH_METHOD
) && dp
->cArgs
== 2 && !dp
->cNamedArgs
) {
4336 DISPPARAMS new_dp
= {args
, NULL
, 3, 0};
4337 V_VT(args
) = VT_BOOL
;
4338 V_BOOL(args
) = VARIANT_FALSE
;
4339 args
[1] = dp
->rgvarg
[0];
4340 args
[2] = dp
->rgvarg
[1];
4342 TRACE("implicit capture\n");
4344 return dispex_call_builtin(dispex
, DISPID_IEVENTTARGET_REMOVEEVENTLISTENER
, &new_dp
, res
, ei
, caller
);
4347 return S_FALSE
; /* fallback to default */
4350 static const IEventTargetVtbl EventTargetVtbl
= {
4351 EventTarget_QueryInterface
,
4353 EventTarget_Release
,
4354 EventTarget_GetTypeInfoCount
,
4355 EventTarget_GetTypeInfo
,
4356 EventTarget_GetIDsOfNames
,
4358 EventTarget_addEventListener
,
4359 EventTarget_removeEventListener
,
4360 EventTarget_dispatchEvent
4363 static EventTarget
*unsafe_impl_from_IEventTarget(IEventTarget
*iface
)
4365 return iface
&& iface
->lpVtbl
== &EventTargetVtbl
? impl_from_IEventTarget(iface
) : NULL
;
4368 static HRESULT
get_gecko_target(IEventTarget
*target
, nsIDOMEventTarget
**ret
)
4370 EventTarget
*event_target
= unsafe_impl_from_IEventTarget(target
);
4371 const event_target_vtbl_t
*vtbl
;
4375 WARN("Not our IEventTarget implementation\n");
4376 return E_INVALIDARG
;
4379 vtbl
= (const event_target_vtbl_t
*)dispex_get_vtbl(&event_target
->dispex
);
4380 nsres
= nsISupports_QueryInterface(vtbl
->get_gecko_target(&event_target
->dispex
),
4381 &IID_nsIDOMEventTarget
, (void**)ret
);
4382 assert(nsres
== NS_OK
);
4386 HRESULT
EventTarget_QI(EventTarget
*event_target
, REFIID riid
, void **ppv
)
4388 if(IsEqualGUID(riid
, &IID_IEventTarget
)) {
4389 if(use_event_quirks(event_target
)) {
4390 WARN("IEventTarget queried, but not supported by in document mode\n");
4392 return E_NOINTERFACE
;
4394 IEventTarget_AddRef(&event_target
->IEventTarget_iface
);
4395 *ppv
= &event_target
->IEventTarget_iface
;
4399 if(dispex_query_interface(&event_target
->dispex
, riid
, ppv
))
4400 return *ppv
? S_OK
: E_NOINTERFACE
;
4402 WARN("(%p)->(%s %p)\n", event_target
, debugstr_mshtml_guid(riid
), ppv
);
4404 return E_NOINTERFACE
;
4407 void EventTarget_init_dispex_info(dispex_data_t
*dispex_info
, compat_mode_t compat_mode
)
4409 static const dispex_hook_t IEventTarget_hooks
[] = {
4410 {DISPID_IEVENTTARGET_ADDEVENTLISTENER
, IEventTarget_addEventListener_hook
},
4411 {DISPID_IEVENTTARGET_REMOVEEVENTLISTENER
, IEventTarget_removeEventListener_hook
},
4415 if(compat_mode
>= COMPAT_MODE_IE9
)
4416 dispex_info_add_interface(dispex_info
, IEventTarget_tid
, IEventTarget_hooks
);
4419 static int event_id_cmp(const void *key
, const struct wine_rb_entry
*entry
)
4421 return wcscmp(key
, WINE_RB_ENTRY_VALUE(entry
, listener_container_t
, entry
)->type
);
4424 void EventTarget_Init(EventTarget
*event_target
, IUnknown
*outer
, dispex_static_data_t
*dispex_data
,
4425 compat_mode_t compat_mode
)
4427 init_dispatch(&event_target
->dispex
, outer
, dispex_data
, compat_mode
);
4428 event_target
->IEventTarget_iface
.lpVtbl
= &EventTargetVtbl
;
4429 wine_rb_init(&event_target
->handler_map
, event_id_cmp
);
4432 void release_event_target(EventTarget
*event_target
)
4434 listener_container_t
*iter
, *iter2
;
4436 WINE_RB_FOR_EACH_ENTRY_DESTRUCTOR(iter
, iter2
, &event_target
->handler_map
, listener_container_t
, entry
) {
4437 while(!list_empty(&iter
->listeners
)) {
4438 event_listener_t
*listener
= LIST_ENTRY(list_head(&iter
->listeners
), event_listener_t
, entry
);
4439 if(listener
->function
)
4440 IDispatch_Release(listener
->function
);
4441 list_remove(&listener
->entry
);