2 * Copyright 2008-2009 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "mshtml_private.h"
31 #include "htmlevent.h"
32 #include "htmlscript.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
39 LISTENER_TYPE_CAPTURE
,
41 LISTENER_TYPE_ONEVENT
,
42 LISTENER_TYPE_ATTACHED
52 struct wine_rb_entry entry
;
53 struct list listeners
;
55 } listener_container_t
;
63 static const WCHAR abortW
[] = {'a','b','o','r','t',0};
64 static const WCHAR beforeactivateW
[] = {'b','e','f','o','r','e','a','c','t','i','v','a','t','e',0};
65 static const WCHAR beforeunloadW
[] = {'b','e','f','o','r','e','u','n','l','o','a','d',0};
66 static const WCHAR blurW
[] = {'b','l','u','r',0};
67 static const WCHAR changeW
[] = {'c','h','a','n','g','e',0};
68 static const WCHAR clickW
[] = {'c','l','i','c','k',0};
69 static const WCHAR contextmenuW
[] = {'c','o','n','t','e','x','t','m','e','n','u',0};
70 static const WCHAR dataavailableW
[] = {'d','a','t','a','a','v','a','i','l','a','b','l','e',0};
71 static const WCHAR dblclickW
[] = {'d','b','l','c','l','i','c','k',0};
72 static const WCHAR dragW
[] = {'d','r','a','g',0};
73 static const WCHAR dragstartW
[] = {'d','r','a','g','s','t','a','r','t',0};
74 static const WCHAR errorW
[] = {'e','r','r','o','r',0};
75 static const WCHAR focusW
[] = {'f','o','c','u','s',0};
76 static const WCHAR focusinW
[] = {'f','o','c','u','s','i','n',0};
77 static const WCHAR focusoutW
[] = {'f','o','c','u','s','o','u','t',0};
78 static const WCHAR helpW
[] = {'h','e','l','p',0};
79 static const WCHAR inputW
[] = {'i','n','p','u','t',0};
80 static const WCHAR keydownW
[] = {'k','e','y','d','o','w','n',0};
81 static const WCHAR keypressW
[] = {'k','e','y','p','r','e','s','s',0};
82 static const WCHAR keyupW
[] = {'k','e','y','u','p',0};
83 static const WCHAR loadW
[] = {'l','o','a','d',0};
84 static const WCHAR messageW
[] = {'m','e','s','s','a','g','e',0};
85 static const WCHAR mousedownW
[] = {'m','o','u','s','e','d','o','w','n',0};
86 static const WCHAR mousemoveW
[] = {'m','o','u','s','e','m','o','v','e',0};
87 static const WCHAR mouseoutW
[] = {'m','o','u','s','e','o','u','t',0};
88 static const WCHAR mouseoverW
[] = {'m','o','u','s','e','o','v','e','r',0};
89 static const WCHAR mouseupW
[] = {'m','o','u','s','e','u','p',0};
90 static const WCHAR mousewheelW
[] = {'m','o','u','s','e','w','h','e','e','l',0};
91 static const WCHAR pasteW
[] = {'p','a','s','t','e',0};
92 static const WCHAR readystatechangeW
[] = {'r','e','a','d','y','s','t','a','t','e','c','h','a','n','g','e',0};
93 static const WCHAR resizeW
[] = {'r','e','s','i','z','e',0};
94 static const WCHAR scrollW
[] = {'s','c','r','o','l','l',0};
95 static const WCHAR selectstartW
[] = {'s','e','l','e','c','t','s','t','a','r','t',0};
96 static const WCHAR selectionchangeW
[] = {'s','e','l','e','c','t','i','o','n','c','h','a','n','g','e',0};
97 static const WCHAR submitW
[] = {'s','u','b','m','i','t',0};
98 static const WCHAR unloadW
[] = {'u','n','l','o','a','d',0};
99 static const WCHAR DOMContentLoadedW
[] = {'D','O','M','C','o','n','t','e','n','t','L','o','a','d','e','d',0};
101 static const WCHAR EventW
[] = {'E','v','e','n','t',0};
102 static const WCHAR UIEventW
[] = {'U','I','E','v','e','n','t',0};
103 static const WCHAR KeyboardEventW
[] = {'K','e','y','b','o','a','r','d','E','v','e','n','t',0};
104 static const WCHAR MouseEventW
[] = {'M','o','u','s','e','E','v','e','n','t',0};
117 static const WCHAR
*event_types
[] = {
135 /* Use Gecko default listener (it's registered on window object for DOM nodes). */
136 #define EVENT_DEFAULTLISTENER 0x0001
137 /* Register Gecko listener on target itself (unlike EVENT_DEFAULTLISTENER). */
138 #define EVENT_BIND_TO_TARGET 0x0002
139 /* Event bubbles by default (unless explicitly specified otherwise). */
140 #define EVENT_BUBBLES 0x0004
141 /* Event is cancelable by default (unless explicitly specified otherwise). */
142 #define EVENT_CANCELABLE 0x0008
143 /* Event may have default handler (so we always have to register Gecko listener). */
144 #define EVENT_HASDEFAULTHANDLERS 0x0020
145 /* Ecent is not supported properly, print FIXME message when it's used. */
146 #define EVENT_FIXME 0x0040
148 /* mouse event flags for fromElement and toElement implementation */
149 #define EVENT_MOUSE_TO_RELATED 0x0100
150 #define EVENT_MOUSE_FROM_RELATED 0x0200
152 static const event_info_t event_info
[] = {
153 {abortW
, EVENT_TYPE_EVENT
, DISPID_EVMETH_ONABORT
,
154 EVENT_BIND_TO_TARGET
},
155 {beforeactivateW
, EVENT_TYPE_EVENT
, DISPID_EVMETH_ONBEFOREACTIVATE
,
156 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
157 {beforeunloadW
, EVENT_TYPE_EVENT
, DISPID_EVMETH_ONBEFOREUNLOAD
,
158 EVENT_DEFAULTLISTENER
| EVENT_CANCELABLE
},
159 {blurW
, EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONBLUR
,
160 EVENT_DEFAULTLISTENER
},
161 {changeW
, EVENT_TYPE_EVENT
, DISPID_EVMETH_ONCHANGE
,
162 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
},
163 {clickW
, EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONCLICK
,
164 EVENT_DEFAULTLISTENER
| EVENT_HASDEFAULTHANDLERS
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
165 {contextmenuW
, EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONCONTEXTMENU
,
166 EVENT_BUBBLES
| EVENT_CANCELABLE
},
167 {dataavailableW
, EVENT_TYPE_EVENT
, DISPID_EVMETH_ONDATAAVAILABLE
,
168 EVENT_FIXME
| EVENT_BUBBLES
},
169 {dblclickW
, EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONDBLCLICK
,
170 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
171 {DOMContentLoadedW
, EVENT_TYPE_EVENT
, 0,
172 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
173 {dragW
, EVENT_TYPE_DRAG
, DISPID_EVMETH_ONDRAG
,
174 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
175 {dragstartW
, EVENT_TYPE_DRAG
, DISPID_EVMETH_ONDRAGSTART
,
176 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
177 {errorW
, EVENT_TYPE_EVENT
, DISPID_EVMETH_ONERROR
,
178 EVENT_BIND_TO_TARGET
},
179 {focusW
, EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONFOCUS
,
180 EVENT_DEFAULTLISTENER
},
181 {focusinW
, EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONFOCUSIN
,
183 {focusoutW
, EVENT_TYPE_FOCUS
, DISPID_EVMETH_ONFOCUSOUT
,
185 {helpW
, EVENT_TYPE_EVENT
, DISPID_EVMETH_ONHELP
,
186 EVENT_BUBBLES
| EVENT_CANCELABLE
},
187 {inputW
, EVENT_TYPE_EVENT
, DISPID_UNKNOWN
,
188 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
},
189 {keydownW
, EVENT_TYPE_KEYBOARD
, DISPID_EVMETH_ONKEYDOWN
,
190 EVENT_DEFAULTLISTENER
| EVENT_HASDEFAULTHANDLERS
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
191 {keypressW
, EVENT_TYPE_KEYBOARD
, DISPID_EVMETH_ONKEYPRESS
,
192 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
193 {keyupW
, EVENT_TYPE_KEYBOARD
, DISPID_EVMETH_ONKEYUP
,
194 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
195 {loadW
, EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONLOAD
,
196 EVENT_BIND_TO_TARGET
},
197 {messageW
, EVENT_TYPE_MESSAGE
, DISPID_EVMETH_ONMESSAGE
,
199 {mousedownW
, EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEDOWN
,
200 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
201 {mousemoveW
, EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEMOVE
,
202 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
| EVENT_MOUSE_FROM_RELATED
},
203 {mouseoutW
, EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEOUT
,
204 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
| EVENT_MOUSE_TO_RELATED
},
205 {mouseoverW
, EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEOVER
,
206 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
| EVENT_MOUSE_FROM_RELATED
},
207 {mouseupW
, EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEUP
,
208 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
209 {mousewheelW
, EVENT_TYPE_MOUSE
, DISPID_EVMETH_ONMOUSEWHEEL
,
211 {pasteW
, EVENT_TYPE_CLIPBOARD
, DISPID_EVMETH_ONPASTE
,
212 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
213 {readystatechangeW
, EVENT_TYPE_EVENT
, DISPID_EVMETH_ONREADYSTATECHANGE
,
215 {resizeW
, EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONRESIZE
,
216 EVENT_DEFAULTLISTENER
},
217 {scrollW
, EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONSCROLL
,
218 EVENT_DEFAULTLISTENER
| EVENT_BUBBLES
/* FIXME: not for elements */},
219 {selectionchangeW
, EVENT_TYPE_EVENT
, DISPID_EVMETH_ONSELECTIONCHANGE
,
221 {selectstartW
, EVENT_TYPE_EVENT
, DISPID_EVMETH_ONSELECTSTART
,
222 EVENT_FIXME
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
223 {submitW
, EVENT_TYPE_EVENT
, DISPID_EVMETH_ONSUBMIT
,
224 EVENT_DEFAULTLISTENER
| EVENT_HASDEFAULTHANDLERS
| EVENT_BUBBLES
| EVENT_CANCELABLE
},
225 {unloadW
, EVENT_TYPE_UIEVENT
, DISPID_EVMETH_ONUNLOAD
,
229 static eventid_t
str_to_eid(const WCHAR
*str
)
233 for(i
=0; i
< sizeof(event_info
)/sizeof(event_info
[0]); i
++) {
234 if(!strcmpW(event_info
[i
].name
, str
))
241 static eventid_t
attr_to_eid(const WCHAR
*str
)
245 if((str
[0] != 'o' && str
[0] != 'O') || (str
[1] != 'n' && str
[1] != 'N'))
248 for(i
=0; i
< sizeof(event_info
)/sizeof(event_info
[0]); i
++) {
249 if(!strcmpW(event_info
[i
].name
, str
+2) && event_info
[i
].dispid
)
256 static listener_container_t
*get_listener_container(EventTarget
*event_target
, const WCHAR
*type
, BOOL alloc
)
258 const event_target_vtbl_t
*vtbl
;
259 listener_container_t
*container
;
260 struct wine_rb_entry
*entry
;
264 entry
= wine_rb_get(&event_target
->handler_map
, type
);
266 return WINE_RB_ENTRY_VALUE(entry
, listener_container_t
, entry
);
270 eid
= str_to_eid(type
);
271 if(eid
!= EVENTID_LAST
&& (event_info
[eid
].flags
& EVENT_FIXME
))
272 FIXME("unimplemented event %s\n", debugstr_w(event_info
[eid
].name
));
274 type_len
= strlenW(type
);
275 container
= heap_alloc(FIELD_OFFSET(listener_container_t
, type
[type_len
+1]));
278 memcpy(container
->type
, type
, (type_len
+ 1) * sizeof(WCHAR
));
279 list_init(&container
->listeners
);
280 vtbl
= dispex_get_vtbl(&event_target
->dispex
);
282 vtbl
->bind_event(&event_target
->dispex
, eid
);
284 FIXME("Unsupported event binding on target %p\n", event_target
);
286 wine_rb_put(&event_target
->handler_map
, container
->type
, &container
->entry
);
290 static void remove_event_listener(EventTarget
*event_target
, const WCHAR
*type_name
, listener_type_t type
, IDispatch
*function
)
292 listener_container_t
*container
;
293 event_listener_t
*listener
;
295 container
= get_listener_container(event_target
, type_name
, FALSE
);
299 LIST_FOR_EACH_ENTRY(listener
, &container
->listeners
, event_listener_t
, entry
) {
300 if(listener
->function
== function
&& listener
->type
== type
) {
301 IDispatch_Release(listener
->function
);
302 list_remove(&listener
->entry
);
309 static HRESULT
get_gecko_target(IEventTarget
*,nsIDOMEventTarget
**);
313 IHTMLEventObj IHTMLEventObj_iface
;
318 VARIANT return_value
;
321 static inline HTMLEventObj
*impl_from_IHTMLEventObj(IHTMLEventObj
*iface
)
323 return CONTAINING_RECORD(iface
, HTMLEventObj
, IHTMLEventObj_iface
);
326 static HRESULT WINAPI
HTMLEventObj_QueryInterface(IHTMLEventObj
*iface
, REFIID riid
, void **ppv
)
328 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
330 TRACE("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
332 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
333 *ppv
= &This
->IHTMLEventObj_iface
;
334 }else if(IsEqualGUID(&IID_IHTMLEventObj
, riid
)) {
335 *ppv
= &This
->IHTMLEventObj_iface
;
336 }else if(dispex_query_interface(&This
->dispex
, riid
, ppv
)) {
337 return *ppv
? S_OK
: E_NOINTERFACE
;
340 WARN("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
341 return E_NOINTERFACE
;
344 IUnknown_AddRef((IUnknown
*)*ppv
);
348 static ULONG WINAPI
HTMLEventObj_AddRef(IHTMLEventObj
*iface
)
350 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
351 LONG ref
= InterlockedIncrement(&This
->ref
);
353 TRACE("(%p) ref=%d\n", This
, ref
);
358 static ULONG WINAPI
HTMLEventObj_Release(IHTMLEventObj
*iface
)
360 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
361 LONG ref
= InterlockedDecrement(&This
->ref
);
363 TRACE("(%p) ref=%d\n", This
, ref
);
367 IDOMEvent_Release(&This
->event
->IDOMEvent_iface
);
368 release_dispex(&This
->dispex
);
375 static HRESULT WINAPI
HTMLEventObj_GetTypeInfoCount(IHTMLEventObj
*iface
, UINT
*pctinfo
)
377 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
378 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
381 static HRESULT WINAPI
HTMLEventObj_GetTypeInfo(IHTMLEventObj
*iface
, UINT iTInfo
,
382 LCID lcid
, ITypeInfo
**ppTInfo
)
384 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
385 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
388 static HRESULT WINAPI
HTMLEventObj_GetIDsOfNames(IHTMLEventObj
*iface
, REFIID riid
,
389 LPOLESTR
*rgszNames
, UINT cNames
,
390 LCID lcid
, DISPID
*rgDispId
)
392 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
393 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
397 static HRESULT WINAPI
HTMLEventObj_Invoke(IHTMLEventObj
*iface
, DISPID dispIdMember
,
398 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
399 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
401 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
402 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
403 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
406 static HRESULT WINAPI
HTMLEventObj_get_srcElement(IHTMLEventObj
*iface
, IHTMLElement
**p
)
408 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
410 TRACE("(%p)->(%p)\n", This
, p
);
417 return IDOMEvent_get_srcElement(&This
->event
->IDOMEvent_iface
, p
);
420 static HRESULT WINAPI
HTMLEventObj_get_altKey(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
422 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
423 cpp_bool ret
= FALSE
;
425 TRACE("(%p)->(%p)\n", This
, p
);
427 if(This
->event
&& This
->event
->mouse_event
)
428 return IDOMMouseEvent_get_altKey(&This
->event
->IDOMMouseEvent_iface
, p
);
430 if(This
->event
&& This
->event
->keyboard_event
)
431 return IDOMKeyboardEvent_get_altKey(&This
->event
->IDOMKeyboardEvent_iface
, p
);
433 *p
= variant_bool(ret
);
437 static HRESULT WINAPI
HTMLEventObj_get_ctrlKey(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
439 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
440 cpp_bool ret
= FALSE
;
442 TRACE("(%p)->(%p)\n", This
, p
);
444 if(This
->event
&& This
->event
->mouse_event
)
445 return IDOMMouseEvent_get_ctrlKey(&This
->event
->IDOMMouseEvent_iface
, p
);
447 if(This
->event
&& This
->event
->keyboard_event
)
448 return IDOMKeyboardEvent_get_ctrlKey(&This
->event
->IDOMKeyboardEvent_iface
, p
);
450 *p
= variant_bool(ret
);
454 static HRESULT WINAPI
HTMLEventObj_get_shiftKey(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
456 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
457 cpp_bool ret
= FALSE
;
459 TRACE("(%p)->(%p)\n", This
, p
);
461 if(This
->event
&& This
->event
->mouse_event
)
462 return IDOMMouseEvent_get_shiftKey(&This
->event
->IDOMMouseEvent_iface
, p
);
464 if(This
->event
&& This
->event
->keyboard_event
)
465 return IDOMKeyboardEvent_get_shiftKey(&This
->event
->IDOMKeyboardEvent_iface
, p
);
467 *p
= variant_bool(ret
);
471 static HRESULT WINAPI
HTMLEventObj_put_returnValue(IHTMLEventObj
*iface
, VARIANT v
)
473 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
475 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&v
));
477 if(V_VT(&v
) != VT_BOOL
) {
478 FIXME("unsupported value %s\n", debugstr_variant(&v
));
479 return DISP_E_BADVARTYPE
;
482 This
->return_value
= v
;
483 if(!V_BOOL(&v
) && This
->event
)
484 IDOMEvent_preventDefault(&This
->event
->IDOMEvent_iface
);
488 static HRESULT WINAPI
HTMLEventObj_get_returnValue(IHTMLEventObj
*iface
, VARIANT
*p
)
490 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
492 TRACE("(%p)->(%p)\n", This
, p
);
495 return VariantCopy(p
, &This
->return_value
);
498 static HRESULT WINAPI
HTMLEventObj_put_cancelBubble(IHTMLEventObj
*iface
, VARIANT_BOOL v
)
500 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
502 TRACE("(%p)->(%x)\n", This
, v
);
505 IDOMEvent_stopPropagation(&This
->event
->IDOMEvent_iface
);
509 static HRESULT WINAPI
HTMLEventObj_get_cancelBubble(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
511 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
513 TRACE("(%p)->(%p)\n", This
, p
);
515 *p
= variant_bool(This
->event
&& This
->event
->stop_propagation
);
519 static HRESULT WINAPI
HTMLEventObj_get_fromElement(IHTMLEventObj
*iface
, IHTMLElement
**p
)
521 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
523 TRACE("(%p)->(%p)\n", This
, p
);
525 if(This
->event
&& This
->event
->mouse_event
)
526 return IDOMMouseEvent_get_fromElement(&This
->event
->IDOMMouseEvent_iface
, p
);
532 static HRESULT WINAPI
HTMLEventObj_get_toElement(IHTMLEventObj
*iface
, IHTMLElement
**p
)
534 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
536 TRACE("(%p)->(%p)\n", This
, p
);
538 if(This
->event
&& This
->event
->mouse_event
)
539 return IDOMMouseEvent_get_toElement(&This
->event
->IDOMMouseEvent_iface
, p
);
545 static HRESULT WINAPI
HTMLEventObj_put_keyCode(IHTMLEventObj
*iface
, LONG v
)
547 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
548 FIXME("(%p)->(%d)\n", This
, v
);
552 static HRESULT WINAPI
HTMLEventObj_get_keyCode(IHTMLEventObj
*iface
, LONG
*p
)
554 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
556 TRACE("(%p)->(%p)\n", This
, p
);
558 if(This
->event
&& This
->event
->keyboard_event
)
559 return IDOMKeyboardEvent_get_keyCode(&This
->event
->IDOMKeyboardEvent_iface
, p
);
565 static HRESULT WINAPI
HTMLEventObj_get_button(IHTMLEventObj
*iface
, LONG
*p
)
567 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
570 TRACE("(%p)->(%p)\n", This
, p
);
572 if(This
->event
&& This
->event
->mouse_event
) {
574 hres
= IDOMMouseEvent_get_button(&This
->event
->IDOMMouseEvent_iface
, &button
);
583 static HRESULT WINAPI
HTMLEventObj_get_type(IHTMLEventObj
*iface
, BSTR
*p
)
585 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
587 TRACE("(%p)->(%p)\n", This
, p
);
594 return IDOMEvent_get_type(&This
->event
->IDOMEvent_iface
, p
);
597 static HRESULT WINAPI
HTMLEventObj_get_qualifier(IHTMLEventObj
*iface
, BSTR
*p
)
599 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
601 FIXME("(%p)->(%p)\n", This
, p
);
607 static HRESULT WINAPI
HTMLEventObj_get_reason(IHTMLEventObj
*iface
, LONG
*p
)
609 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
611 FIXME("(%p)->(%p)\n", This
, p
);
617 static HRESULT WINAPI
HTMLEventObj_get_x(IHTMLEventObj
*iface
, LONG
*p
)
619 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
622 TRACE("(%p)->(%p)\n", This
, p
);
624 if(This
->event
&& This
->event
->ui_event
) {
627 /* NOTE: pageX is not exactly right here. */
628 nsres
= nsIDOMUIEvent_GetPageX(This
->event
->ui_event
, &x
);
629 assert(nsres
== NS_OK
);
636 static HRESULT WINAPI
HTMLEventObj_get_y(IHTMLEventObj
*iface
, LONG
*p
)
638 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
641 TRACE("(%p)->(%p)\n", This
, p
);
643 if(This
->event
&& This
->event
->ui_event
) {
646 /* NOTE: pageY is not exactly right here. */
647 nsres
= nsIDOMUIEvent_GetPageY(This
->event
->ui_event
, &y
);
648 assert(nsres
== NS_OK
);
655 static HRESULT WINAPI
HTMLEventObj_get_clientX(IHTMLEventObj
*iface
, LONG
*p
)
657 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
659 TRACE("(%p)->(%p)\n", This
, p
);
661 if(This
->event
&& This
->event
->mouse_event
)
662 return IDOMMouseEvent_get_clientX(&This
->event
->IDOMMouseEvent_iface
, p
);
668 static HRESULT WINAPI
HTMLEventObj_get_clientY(IHTMLEventObj
*iface
, LONG
*p
)
670 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
672 TRACE("(%p)->(%p)\n", This
, p
);
674 if(This
->event
&& This
->event
->mouse_event
)
675 return IDOMMouseEvent_get_clientY(&This
->event
->IDOMMouseEvent_iface
, p
);
681 static HRESULT WINAPI
HTMLEventObj_get_offsetX(IHTMLEventObj
*iface
, LONG
*p
)
683 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
685 TRACE("(%p)->(%p)\n", This
, p
);
687 if(This
->event
&& This
->event
->mouse_event
)
688 return IDOMMouseEvent_get_offsetX(&This
->event
->IDOMMouseEvent_iface
, p
);
694 static HRESULT WINAPI
HTMLEventObj_get_offsetY(IHTMLEventObj
*iface
, LONG
*p
)
696 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
698 TRACE("(%p)->(%p)\n", This
, p
);
700 if(This
->event
&& This
->event
->mouse_event
)
701 return IDOMMouseEvent_get_offsetY(&This
->event
->IDOMMouseEvent_iface
, p
);
707 static HRESULT WINAPI
HTMLEventObj_get_screenX(IHTMLEventObj
*iface
, LONG
*p
)
709 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
711 TRACE("(%p)->(%p)\n", This
, p
);
713 if(This
->event
&& This
->event
->mouse_event
)
714 return IDOMMouseEvent_get_screenX(&This
->event
->IDOMMouseEvent_iface
, p
);
720 static HRESULT WINAPI
HTMLEventObj_get_screenY(IHTMLEventObj
*iface
, LONG
*p
)
722 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
724 TRACE("(%p)->(%p)\n", This
, p
);
726 if(This
->event
&& This
->event
->mouse_event
)
727 return IDOMMouseEvent_get_screenY(&This
->event
->IDOMMouseEvent_iface
, p
);
733 static HRESULT WINAPI
HTMLEventObj_get_srcFilter(IHTMLEventObj
*iface
, IDispatch
**p
)
735 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
737 FIXME("(%p)->(%p)\n", This
, p
);
743 static const IHTMLEventObjVtbl HTMLEventObjVtbl
= {
744 HTMLEventObj_QueryInterface
,
746 HTMLEventObj_Release
,
747 HTMLEventObj_GetTypeInfoCount
,
748 HTMLEventObj_GetTypeInfo
,
749 HTMLEventObj_GetIDsOfNames
,
751 HTMLEventObj_get_srcElement
,
752 HTMLEventObj_get_altKey
,
753 HTMLEventObj_get_ctrlKey
,
754 HTMLEventObj_get_shiftKey
,
755 HTMLEventObj_put_returnValue
,
756 HTMLEventObj_get_returnValue
,
757 HTMLEventObj_put_cancelBubble
,
758 HTMLEventObj_get_cancelBubble
,
759 HTMLEventObj_get_fromElement
,
760 HTMLEventObj_get_toElement
,
761 HTMLEventObj_put_keyCode
,
762 HTMLEventObj_get_keyCode
,
763 HTMLEventObj_get_button
,
764 HTMLEventObj_get_type
,
765 HTMLEventObj_get_qualifier
,
766 HTMLEventObj_get_reason
,
769 HTMLEventObj_get_clientX
,
770 HTMLEventObj_get_clientY
,
771 HTMLEventObj_get_offsetX
,
772 HTMLEventObj_get_offsetY
,
773 HTMLEventObj_get_screenX
,
774 HTMLEventObj_get_screenY
,
775 HTMLEventObj_get_srcFilter
778 static inline HTMLEventObj
*unsafe_impl_from_IHTMLEventObj(IHTMLEventObj
*iface
)
780 return iface
->lpVtbl
== &HTMLEventObjVtbl
? impl_from_IHTMLEventObj(iface
) : NULL
;
783 static const tid_t HTMLEventObj_iface_tids
[] = {
788 static dispex_static_data_t HTMLEventObj_dispex
= {
791 HTMLEventObj_iface_tids
794 static HTMLEventObj
*alloc_event_obj(DOMEvent
*event
)
796 HTMLEventObj
*event_obj
;
798 event_obj
= heap_alloc_zero(sizeof(*event_obj
));
802 event_obj
->IHTMLEventObj_iface
.lpVtbl
= &HTMLEventObjVtbl
;
804 event_obj
->event
= event
;
806 IDOMEvent_AddRef(&event
->IDOMEvent_iface
);
808 init_dispex(&event_obj
->dispex
, (IUnknown
*)&event_obj
->IHTMLEventObj_iface
, &HTMLEventObj_dispex
);
812 HRESULT
create_event_obj(IHTMLEventObj
**ret
)
814 HTMLEventObj
*event_obj
;
816 event_obj
= alloc_event_obj(NULL
);
818 return E_OUTOFMEMORY
;
820 *ret
= &event_obj
->IHTMLEventObj_iface
;
824 static inline DOMEvent
*impl_from_IDOMEvent(IDOMEvent
*iface
)
826 return CONTAINING_RECORD(iface
, DOMEvent
, IDOMEvent_iface
);
829 static const IDOMEventVtbl DOMEventVtbl
;
831 static inline DOMEvent
*unsafe_impl_from_IDOMEvent(IDOMEvent
*iface
)
833 return iface
&& iface
->lpVtbl
== &DOMEventVtbl
? impl_from_IDOMEvent(iface
) : NULL
;
836 static HRESULT WINAPI
DOMEvent_QueryInterface(IDOMEvent
*iface
, REFIID riid
, void **ppv
)
838 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
840 TRACE("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
842 if(IsEqualGUID(&IID_IUnknown
, riid
))
843 *ppv
= &This
->IDOMEvent_iface
;
844 else if(IsEqualGUID(&IID_IDOMEvent
, riid
))
845 *ppv
= &This
->IDOMEvent_iface
;
846 else if(This
->ui_event
&& IsEqualGUID(&IID_IDOMUIEvent
, riid
))
847 *ppv
= &This
->IDOMUIEvent_iface
;
848 else if(This
->mouse_event
&& IsEqualGUID(&IID_IDOMMouseEvent
, riid
))
849 *ppv
= &This
->IDOMMouseEvent_iface
;
850 else if(This
->keyboard_event
&& IsEqualGUID(&IID_IDOMKeyboardEvent
, riid
))
851 *ppv
= &This
->IDOMKeyboardEvent_iface
;
852 else if(dispex_query_interface(&This
->dispex
, riid
, ppv
))
853 return *ppv
? S_OK
: E_NOINTERFACE
;
856 WARN("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
857 return E_NOINTERFACE
;
860 IUnknown_AddRef((IUnknown
*)*ppv
);
864 static ULONG WINAPI
DOMEvent_AddRef(IDOMEvent
*iface
)
866 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
867 LONG ref
= InterlockedIncrement(&This
->ref
);
869 TRACE("(%p) ref=%u\n", This
, ref
);
874 static ULONG WINAPI
DOMEvent_Release(IDOMEvent
*iface
)
876 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
877 LONG ref
= InterlockedDecrement(&This
->ref
);
879 TRACE("(%p) ref=%u\n", This
, ref
);
883 nsIDOMUIEvent_Release(This
->ui_event
);
884 if(This
->mouse_event
)
885 nsIDOMMouseEvent_Release(This
->mouse_event
);
887 IEventTarget_Release(&This
->target
->IEventTarget_iface
);
888 nsIDOMEvent_Release(This
->nsevent
);
889 release_dispex(&This
->dispex
);
890 heap_free(This
->type
);
897 static HRESULT WINAPI
DOMEvent_GetTypeInfoCount(IDOMEvent
*iface
, UINT
*pctinfo
)
899 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
900 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
903 static HRESULT WINAPI
DOMEvent_GetTypeInfo(IDOMEvent
*iface
, UINT iTInfo
,
904 LCID lcid
, ITypeInfo
**ppTInfo
)
906 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
907 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
910 static HRESULT WINAPI
DOMEvent_GetIDsOfNames(IDOMEvent
*iface
, REFIID riid
,
911 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
913 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
914 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
918 static HRESULT WINAPI
DOMEvent_Invoke(IDOMEvent
*iface
, DISPID dispIdMember
,
919 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
920 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
922 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
923 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
924 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
927 static HRESULT WINAPI
DOMEvent_get_bubbles(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
929 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
931 TRACE("(%p)->(%p)\n", This
, p
);
933 *p
= variant_bool(This
->bubbles
);
937 static HRESULT WINAPI
DOMEvent_get_cancelable(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
939 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
941 TRACE("(%p)->(%p)\n", This
, p
);
943 *p
= variant_bool(This
->cancelable
);
947 static HRESULT WINAPI
DOMEvent_get_currentTarget(IDOMEvent
*iface
, IEventTarget
**p
)
949 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
951 TRACE("(%p)->(%p)\n", This
, p
);
953 if(This
->current_target
)
954 IEventTarget_AddRef(*p
= &This
->current_target
->IEventTarget_iface
);
960 static HRESULT WINAPI
DOMEvent_get_defaultPrevented(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
962 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
964 TRACE("(%p)->(%p)\n", This
, p
);
966 *p
= variant_bool(This
->prevent_default
);
970 static HRESULT WINAPI
DOMEvent_get_eventPhase(IDOMEvent
*iface
, USHORT
*p
)
972 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
974 TRACE("(%p)->(%p)\n", This
, p
);
980 static HRESULT WINAPI
DOMEvent_get_target(IDOMEvent
*iface
, IEventTarget
**p
)
982 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
984 TRACE("(%p)->(%p)\n", This
, p
);
987 IEventTarget_AddRef(*p
= &This
->target
->IEventTarget_iface
);
993 static HRESULT WINAPI
DOMEvent_get_timeStamp(IDOMEvent
*iface
, ULONGLONG
*p
)
995 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
997 TRACE("(%p)->(%p)\n", This
, p
);
999 *p
= This
->time_stamp
;
1003 static HRESULT WINAPI
DOMEvent_get_type(IDOMEvent
*iface
, BSTR
*p
)
1005 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1007 TRACE("(%p)->(%p)\n", This
, p
);
1010 *p
= SysAllocString(This
->type
);
1012 return E_OUTOFMEMORY
;
1020 #define nsIDOMEvent_InitEvent(_this,type,bubbles,cancelable) \
1021 ((void (WINAPI*)(void*,nsIDOMEvent*,const nsAString*,cpp_bool,cpp_bool)) \
1022 &call_thiscall_func)((_this)->lpVtbl->InitEvent,_this,type,bubbles,cancelable)
1026 static HRESULT WINAPI
DOMEvent_initEvent(IDOMEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
, VARIANT_BOOL cancelable
)
1028 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1031 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_w(type
), can_bubble
, cancelable
);
1034 TRACE("called on already dispatched event\n");
1038 heap_free(This
->type
);
1039 This
->type
= heap_strdupW(type
);
1041 return E_OUTOFMEMORY
;
1042 This
->event_id
= str_to_eid(type
);
1044 This
->bubbles
= !!can_bubble
;
1045 This
->cancelable
= !!cancelable
;
1047 nsAString_InitDepend(&nsstr
, type
);
1048 nsIDOMEvent_InitEvent(This
->nsevent
, &nsstr
, This
->bubbles
, This
->cancelable
);
1049 nsAString_Finish(&nsstr
);
1054 static HRESULT WINAPI
DOMEvent_preventDefault(IDOMEvent
*iface
)
1056 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1058 TRACE("(%p)\n", This
);
1060 if(This
->current_target
&& This
->cancelable
) {
1061 This
->prevent_default
= TRUE
;
1062 nsIDOMEvent_PreventDefault(This
->nsevent
);
1067 static HRESULT WINAPI
DOMEvent_stopPropagation(IDOMEvent
*iface
)
1069 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1071 TRACE("(%p)\n", This
);
1073 This
->stop_propagation
= TRUE
;
1074 nsIDOMEvent_StopPropagation(This
->nsevent
);
1078 static HRESULT WINAPI
DOMEvent_stopImmediatePropagation(IDOMEvent
*iface
)
1080 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1082 TRACE("(%p)\n", This
);
1084 This
->stop_immediate_propagation
= This
->stop_propagation
= TRUE
;
1085 nsIDOMEvent_StopImmediatePropagation(This
->nsevent
);
1089 static HRESULT WINAPI
DOMEvent_get_isTrusted(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
1091 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1092 FIXME("(%p)->(%p)\n", This
, p
);
1096 static HRESULT WINAPI
DOMEvent_put_cancelBubble(IDOMEvent
*iface
, VARIANT_BOOL v
)
1098 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1099 FIXME("(%p)->(%x)\n", This
, v
);
1103 static HRESULT WINAPI
DOMEvent_get_cancelBubble(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
1105 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1106 FIXME("(%p)->(%p)\n", This
, p
);
1110 static HRESULT WINAPI
DOMEvent_get_srcElement(IDOMEvent
*iface
, IHTMLElement
**p
)
1112 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1114 TRACE("(%p)->(%p)\n", This
, p
);
1117 IDispatchEx_QueryInterface(&This
->target
->dispex
.IDispatchEx_iface
, &IID_IHTMLElement
, (void**)p
);
1123 static const IDOMEventVtbl DOMEventVtbl
= {
1124 DOMEvent_QueryInterface
,
1127 DOMEvent_GetTypeInfoCount
,
1128 DOMEvent_GetTypeInfo
,
1129 DOMEvent_GetIDsOfNames
,
1131 DOMEvent_get_bubbles
,
1132 DOMEvent_get_cancelable
,
1133 DOMEvent_get_currentTarget
,
1134 DOMEvent_get_defaultPrevented
,
1135 DOMEvent_get_eventPhase
,
1136 DOMEvent_get_target
,
1137 DOMEvent_get_timeStamp
,
1140 DOMEvent_preventDefault
,
1141 DOMEvent_stopPropagation
,
1142 DOMEvent_stopImmediatePropagation
,
1143 DOMEvent_get_isTrusted
,
1144 DOMEvent_put_cancelBubble
,
1145 DOMEvent_get_cancelBubble
,
1146 DOMEvent_get_srcElement
1149 static inline DOMEvent
*impl_from_IDOMUIEvent(IDOMUIEvent
*iface
)
1151 return CONTAINING_RECORD(iface
, DOMEvent
, IDOMUIEvent_iface
);
1154 static HRESULT WINAPI
DOMUIEvent_QueryInterface(IDOMUIEvent
*iface
, REFIID riid
, void **ppv
)
1156 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1157 return IDOMEvent_QueryInterface(&This
->IDOMEvent_iface
, riid
, ppv
);
1160 static ULONG WINAPI
DOMUIEvent_AddRef(IDOMUIEvent
*iface
)
1162 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1163 return IDOMEvent_AddRef(&This
->IDOMEvent_iface
);
1166 static ULONG WINAPI
DOMUIEvent_Release(IDOMUIEvent
*iface
)
1168 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1169 return IDOMEvent_Release(&This
->IDOMEvent_iface
);
1172 static HRESULT WINAPI
DOMUIEvent_GetTypeInfoCount(IDOMUIEvent
*iface
, UINT
*pctinfo
)
1174 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1175 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
1178 static HRESULT WINAPI
DOMUIEvent_GetTypeInfo(IDOMUIEvent
*iface
, UINT iTInfo
,
1179 LCID lcid
, ITypeInfo
**ppTInfo
)
1181 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1182 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1185 static HRESULT WINAPI
DOMUIEvent_GetIDsOfNames(IDOMUIEvent
*iface
, REFIID riid
,
1186 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1188 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1189 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1193 static HRESULT WINAPI
DOMUIEvent_Invoke(IDOMUIEvent
*iface
, DISPID dispIdMember
,
1194 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1195 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1197 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1198 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1199 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1202 static HRESULT WINAPI
DOMUIEvent_get_view(IDOMUIEvent
*iface
, IHTMLWindow2
**p
)
1204 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1205 mozIDOMWindowProxy
*moz_window
;
1206 HTMLOuterWindow
*view
= NULL
;
1209 TRACE("(%p)->(%p)\n", This
, p
);
1211 nsres
= nsIDOMUIEvent_GetView(This
->ui_event
, &moz_window
);
1212 if(NS_FAILED(nsres
))
1216 view
= mozwindow_to_window(moz_window
);
1217 mozIDOMWindowProxy_Release(moz_window
);
1220 IHTMLWindow2_AddRef((*p
= &view
->base
.inner_window
->base
.IHTMLWindow2_iface
));
1226 static HRESULT WINAPI
DOMUIEvent_get_detail(IDOMUIEvent
*iface
, LONG
*p
)
1228 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1232 TRACE("(%p)->(%p)\n", This
, p
);
1234 nsres
= nsIDOMUIEvent_GetDetail(This
->ui_event
, &detail
);
1235 if(NS_FAILED(nsres
))
1242 static HRESULT WINAPI
DOMUIEvent_initUIEvent(IDOMUIEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
1243 VARIANT_BOOL cancelable
, IHTMLWindow2
*view
, LONG detail
)
1245 DOMEvent
*This
= impl_from_IDOMUIEvent(iface
);
1250 TRACE("(%p)->(%s %x %x %p %x)\n", This
, debugstr_w(type
), can_bubble
, cancelable
, view
, detail
);
1253 TRACE("called on already dispatched event\n");
1258 FIXME("view argument is not supported\n");
1260 hres
= IDOMEvent_initEvent(&This
->IDOMEvent_iface
, type
, can_bubble
, cancelable
);
1264 nsAString_InitDepend(&type_str
, type
);
1265 nsres
= nsIDOMUIEvent_InitUIEvent(This
->ui_event
, &type_str
, can_bubble
, cancelable
,
1266 NULL
/* FIXME */, detail
);
1267 nsAString_Finish(&type_str
);
1268 if(NS_FAILED(nsres
)) {
1269 FIXME("InitUIEvent failed: %08x\n", nsres
);
1276 static const IDOMUIEventVtbl DOMUIEventVtbl
= {
1277 DOMUIEvent_QueryInterface
,
1280 DOMUIEvent_GetTypeInfoCount
,
1281 DOMUIEvent_GetTypeInfo
,
1282 DOMUIEvent_GetIDsOfNames
,
1284 DOMUIEvent_get_view
,
1285 DOMUIEvent_get_detail
,
1286 DOMUIEvent_initUIEvent
1289 static inline DOMEvent
*impl_from_IDOMMouseEvent(IDOMMouseEvent
*iface
)
1291 return CONTAINING_RECORD(iface
, DOMEvent
, IDOMMouseEvent_iface
);
1294 static HRESULT WINAPI
DOMMouseEvent_QueryInterface(IDOMMouseEvent
*iface
, REFIID riid
, void **ppv
)
1296 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1297 return IDOMEvent_QueryInterface(&This
->IDOMEvent_iface
, riid
, ppv
);
1300 static ULONG WINAPI
DOMMouseEvent_AddRef(IDOMMouseEvent
*iface
)
1302 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1303 return IDOMEvent_AddRef(&This
->IDOMEvent_iface
);
1306 static ULONG WINAPI
DOMMouseEvent_Release(IDOMMouseEvent
*iface
)
1308 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1309 return IDOMEvent_Release(&This
->IDOMEvent_iface
);
1312 static HRESULT WINAPI
DOMMouseEvent_GetTypeInfoCount(IDOMMouseEvent
*iface
, UINT
*pctinfo
)
1314 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1315 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
1318 static HRESULT WINAPI
DOMMouseEvent_GetTypeInfo(IDOMMouseEvent
*iface
, UINT iTInfo
,
1319 LCID lcid
, ITypeInfo
**ppTInfo
)
1321 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1322 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1325 static HRESULT WINAPI
DOMMouseEvent_GetIDsOfNames(IDOMMouseEvent
*iface
, REFIID riid
,
1326 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1328 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1329 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1333 static HRESULT WINAPI
DOMMouseEvent_Invoke(IDOMMouseEvent
*iface
, DISPID dispIdMember
,
1334 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1335 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1337 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1338 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1339 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1342 static HRESULT WINAPI
DOMMouseEvent_get_screenX(IDOMMouseEvent
*iface
, LONG
*p
)
1344 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1348 TRACE("(%p)->(%p)\n", This
, p
);
1350 nsres
= nsIDOMMouseEvent_GetScreenX(This
->mouse_event
, &screen_x
);
1351 if(NS_FAILED(nsres
))
1358 static HRESULT WINAPI
DOMMouseEvent_get_screenY(IDOMMouseEvent
*iface
, LONG
*p
)
1360 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1364 TRACE("(%p)->(%p)\n", This
, p
);
1366 nsres
= nsIDOMMouseEvent_GetScreenY(This
->mouse_event
, &screen_y
);
1367 if(NS_FAILED(nsres
))
1374 static HRESULT WINAPI
DOMMouseEvent_get_clientX(IDOMMouseEvent
*iface
, LONG
*p
)
1376 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1380 TRACE("(%p)->(%p)\n", This
, p
);
1382 nsres
= nsIDOMMouseEvent_GetClientX(This
->mouse_event
, &client_x
);
1383 if(NS_FAILED(nsres
))
1390 static HRESULT WINAPI
DOMMouseEvent_get_clientY(IDOMMouseEvent
*iface
, LONG
*p
)
1392 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1396 TRACE("(%p)->(%p)\n", This
, p
);
1398 nsres
= nsIDOMMouseEvent_GetClientY(This
->mouse_event
, &client_y
);
1399 if(NS_FAILED(nsres
))
1406 static HRESULT WINAPI
DOMMouseEvent_get_ctrlKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1408 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1412 TRACE("(%p)->(%p)\n", This
, p
);
1414 nsres
= nsIDOMMouseEvent_GetCtrlKey(This
->mouse_event
, &r
);
1415 if(NS_FAILED(nsres
))
1418 *p
= variant_bool(r
);
1422 static HRESULT WINAPI
DOMMouseEvent_get_shiftKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1424 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1428 TRACE("(%p)->(%p)\n", This
, p
);
1430 nsres
= nsIDOMMouseEvent_GetShiftKey(This
->mouse_event
, &r
);
1431 if(NS_FAILED(nsres
))
1434 *p
= variant_bool(r
);
1438 static HRESULT WINAPI
DOMMouseEvent_get_altKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1440 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1444 TRACE("(%p)->(%p)\n", This
, p
);
1446 nsres
= nsIDOMMouseEvent_GetAltKey(This
->mouse_event
, &r
);
1447 if(NS_FAILED(nsres
))
1450 *p
= variant_bool(r
);
1454 static HRESULT WINAPI
DOMMouseEvent_get_metaKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1456 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1460 TRACE("(%p)->(%p)\n", This
, p
);
1462 nsres
= nsIDOMMouseEvent_GetMetaKey(This
->mouse_event
, &r
);
1463 if(NS_FAILED(nsres
))
1466 *p
= variant_bool(r
);
1470 static HRESULT WINAPI
DOMMouseEvent_get_button(IDOMMouseEvent
*iface
, USHORT
*p
)
1472 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1476 TRACE("(%p)->(%p)\n", This
, p
);
1478 nsres
= nsIDOMMouseEvent_GetButton(This
->mouse_event
, &r
);
1479 if(NS_FAILED(nsres
))
1486 static HRESULT WINAPI
DOMMouseEvent_get_relatedTarget(IDOMMouseEvent
*iface
, IEventTarget
**p
)
1488 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1489 nsIDOMEventTarget
*related_target
;
1490 nsIDOMNode
*target_node
;
1495 TRACE("(%p)->(%p)\n", This
, p
);
1497 nsres
= nsIDOMMouseEvent_GetRelatedTarget(This
->mouse_event
, &related_target
);
1498 if(NS_FAILED(nsres
))
1501 if(!related_target
) {
1506 nsres
= nsIDOMEventTarget_QueryInterface(related_target
, &IID_nsIDOMNode
, (void**)&target_node
);
1507 nsIDOMEventTarget_Release(related_target
);
1508 if(NS_FAILED(nsres
)) {
1509 FIXME("Only node targets supported\n");
1513 hres
= get_node(target_node
, TRUE
, &node
);
1514 nsIDOMNode_Release(target_node
);
1518 *p
= &node
->event_target
.IEventTarget_iface
;
1522 static HRESULT WINAPI
DOMMouseEvent_initMouseEvent(IDOMMouseEvent
*iface
, BSTR type
,
1523 VARIANT_BOOL can_bubble
, VARIANT_BOOL cancelable
, IHTMLWindow2
*view
, LONG detail
,
1524 LONG screen_x
, LONG screen_y
, LONG client_x
, LONG client_y
, VARIANT_BOOL ctrl_key
,
1525 VARIANT_BOOL alt_key
, VARIANT_BOOL shift_key
, VARIANT_BOOL meta_key
, USHORT button
,
1526 IEventTarget
*related_target
)
1528 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1529 nsIDOMEventTarget
*nstarget
= NULL
;
1534 TRACE("(%p)->(%s %x %x %p %d %d %d %d %d %x %x %x %x %u %p)\n", This
, debugstr_w(type
),
1535 can_bubble
, cancelable
, view
, detail
, screen_x
, screen_y
, client_x
, client_y
,
1536 ctrl_key
, alt_key
, shift_key
, meta_key
, button
, related_target
);
1539 TRACE("called on already dispatched event\n");
1544 FIXME("view argument is not supported\n");
1546 if(related_target
) {
1547 hres
= get_gecko_target(related_target
, &nstarget
);
1552 hres
= IDOMEvent_initEvent(&This
->IDOMEvent_iface
, type
, can_bubble
, cancelable
);
1553 if(SUCCEEDED(hres
)) {
1554 nsAString_InitDepend(&type_str
, type
);
1555 nsres
= nsIDOMMouseEvent_InitMouseEvent(This
->mouse_event
, &type_str
, can_bubble
, cancelable
,
1556 NULL
/* FIXME */, detail
, screen_x
, screen_y
,
1557 client_x
, client_y
, ctrl_key
, alt_key
, shift_key
,
1558 meta_key
, button
, nstarget
);
1559 nsAString_Finish(&type_str
);
1560 if(NS_FAILED(nsres
)) {
1561 FIXME("InitMouseEvent failed: %08x\n", nsres
);
1567 nsIDOMEventTarget_Release(nstarget
);
1571 static HRESULT WINAPI
DOMMouseEvent_getModifierState(IDOMMouseEvent
*iface
, BSTR key
,
1572 VARIANT_BOOL
*activated
)
1574 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1575 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(key
), activated
);
1579 static HRESULT WINAPI
DOMMouseEvent_get_buttons(IDOMMouseEvent
*iface
, USHORT
*p
)
1581 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1585 TRACE("(%p)->(%p)\n", This
, p
);
1587 nsres
= nsIDOMMouseEvent_GetButtons(This
->mouse_event
, &r
);
1588 if(NS_FAILED(nsres
))
1595 static HRESULT WINAPI
DOMMouseEvent_get_fromElement(IDOMMouseEvent
*iface
, IHTMLElement
**p
)
1597 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1598 IEventTarget
*related_target
= NULL
;
1600 TRACE("(%p)->(%p)\n", This
, p
);
1602 if(This
->event_id
!= EVENTID_LAST
) {
1603 HRESULT hres
= S_OK
;
1604 if(event_info
[This
->event_id
].flags
& EVENT_MOUSE_FROM_RELATED
)
1605 hres
= IDOMMouseEvent_get_relatedTarget(&This
->IDOMMouseEvent_iface
, &related_target
);
1606 else if(event_info
[This
->event_id
].flags
& EVENT_MOUSE_TO_RELATED
)
1607 hres
= IDOMEvent_get_target(&This
->IDOMEvent_iface
, &related_target
);
1612 if(!related_target
) {
1617 IEventTarget_QueryInterface(related_target
, &IID_IHTMLElement
, (void**)p
);
1621 static HRESULT WINAPI
DOMMouseEvent_get_toElement(IDOMMouseEvent
*iface
, IHTMLElement
**p
)
1623 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1624 IEventTarget
*related_target
= NULL
;
1626 TRACE("(%p)->(%p)\n", This
, p
);
1628 if(This
->event_id
!= EVENTID_LAST
) {
1629 HRESULT hres
= S_OK
;
1630 if(event_info
[This
->event_id
].flags
& EVENT_MOUSE_TO_RELATED
)
1631 hres
= IDOMMouseEvent_get_relatedTarget(&This
->IDOMMouseEvent_iface
, &related_target
);
1632 else if(event_info
[This
->event_id
].flags
& EVENT_MOUSE_FROM_RELATED
)
1633 hres
= IDOMEvent_get_target(&This
->IDOMEvent_iface
, &related_target
);
1638 if(!related_target
) {
1643 IEventTarget_QueryInterface(related_target
, &IID_IHTMLElement
, (void**)p
);
1647 static HRESULT WINAPI
DOMMouseEvent_get_x(IDOMMouseEvent
*iface
, LONG
*p
)
1649 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1650 FIXME("(%p)->(%p)\n", This
, p
);
1654 static HRESULT WINAPI
DOMMouseEvent_get_y(IDOMMouseEvent
*iface
, LONG
*p
)
1656 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1657 FIXME("(%p)->(%p)\n", This
, p
);
1661 static HRESULT WINAPI
DOMMouseEvent_get_offsetX(IDOMMouseEvent
*iface
, LONG
*p
)
1663 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1665 FIXME("(%p)->(%p) returning 0\n", This
, p
);
1671 static HRESULT WINAPI
DOMMouseEvent_get_offsetY(IDOMMouseEvent
*iface
, LONG
*p
)
1673 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1675 FIXME("(%p)->(%p) returning 0\n", This
, p
);
1681 static HRESULT WINAPI
DOMMouseEvent_get_pageX(IDOMMouseEvent
*iface
, LONG
*p
)
1683 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1687 TRACE("(%p)->(%p)\n", This
, p
);
1689 nsres
= nsIDOMMouseEvent_GetPageX(This
->mouse_event
, &r
);
1690 if(NS_FAILED(nsres
))
1697 static HRESULT WINAPI
DOMMouseEvent_get_pageY(IDOMMouseEvent
*iface
, LONG
*p
)
1699 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1703 TRACE("(%p)->(%p)\n", This
, p
);
1705 nsres
= nsIDOMMouseEvent_GetPageY(This
->mouse_event
, &r
);
1706 if(NS_FAILED(nsres
))
1713 static HRESULT WINAPI
DOMMouseEvent_get_layerX(IDOMMouseEvent
*iface
, LONG
*p
)
1715 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1716 FIXME("(%p)->(%p)\n", This
, p
);
1720 static HRESULT WINAPI
DOMMouseEvent_get_layerY(IDOMMouseEvent
*iface
, LONG
*p
)
1722 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1723 FIXME("(%p)->(%p)\n", This
, p
);
1727 static HRESULT WINAPI
DOMMouseEvent_get_which(IDOMMouseEvent
*iface
, USHORT
*p
)
1729 DOMEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1733 TRACE("(%p)->(%p)\n", This
, p
);
1735 nsres
= nsIDOMMouseEvent_GetWhich(This
->mouse_event
, &r
);
1736 if(NS_FAILED(nsres
))
1743 static const IDOMMouseEventVtbl DOMMouseEventVtbl
= {
1744 DOMMouseEvent_QueryInterface
,
1745 DOMMouseEvent_AddRef
,
1746 DOMMouseEvent_Release
,
1747 DOMMouseEvent_GetTypeInfoCount
,
1748 DOMMouseEvent_GetTypeInfo
,
1749 DOMMouseEvent_GetIDsOfNames
,
1750 DOMMouseEvent_Invoke
,
1751 DOMMouseEvent_get_screenX
,
1752 DOMMouseEvent_get_screenY
,
1753 DOMMouseEvent_get_clientX
,
1754 DOMMouseEvent_get_clientY
,
1755 DOMMouseEvent_get_ctrlKey
,
1756 DOMMouseEvent_get_shiftKey
,
1757 DOMMouseEvent_get_altKey
,
1758 DOMMouseEvent_get_metaKey
,
1759 DOMMouseEvent_get_button
,
1760 DOMMouseEvent_get_relatedTarget
,
1761 DOMMouseEvent_initMouseEvent
,
1762 DOMMouseEvent_getModifierState
,
1763 DOMMouseEvent_get_buttons
,
1764 DOMMouseEvent_get_fromElement
,
1765 DOMMouseEvent_get_toElement
,
1766 DOMMouseEvent_get_x
,
1767 DOMMouseEvent_get_y
,
1768 DOMMouseEvent_get_offsetX
,
1769 DOMMouseEvent_get_offsetY
,
1770 DOMMouseEvent_get_pageX
,
1771 DOMMouseEvent_get_pageY
,
1772 DOMMouseEvent_get_layerX
,
1773 DOMMouseEvent_get_layerY
,
1774 DOMMouseEvent_get_which
1777 static inline DOMEvent
*impl_from_IDOMKeyboardEvent(IDOMKeyboardEvent
*iface
)
1779 return CONTAINING_RECORD(iface
, DOMEvent
, IDOMKeyboardEvent_iface
);
1782 static HRESULT WINAPI
DOMKeyboardEvent_QueryInterface(IDOMKeyboardEvent
*iface
, REFIID riid
, void **ppv
)
1784 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1785 return IDOMEvent_QueryInterface(&This
->IDOMEvent_iface
, riid
, ppv
);
1788 static ULONG WINAPI
DOMKeyboardEvent_AddRef(IDOMKeyboardEvent
*iface
)
1790 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1791 return IDOMEvent_AddRef(&This
->IDOMEvent_iface
);
1794 static ULONG WINAPI
DOMKeyboardEvent_Release(IDOMKeyboardEvent
*iface
)
1796 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1797 return IDOMEvent_Release(&This
->IDOMEvent_iface
);
1800 static HRESULT WINAPI
DOMKeyboardEvent_GetTypeInfoCount(IDOMKeyboardEvent
*iface
, UINT
*pctinfo
)
1802 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1803 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
1806 static HRESULT WINAPI
DOMKeyboardEvent_GetTypeInfo(IDOMKeyboardEvent
*iface
, UINT iTInfo
,
1807 LCID lcid
, ITypeInfo
**ppTInfo
)
1809 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1810 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1813 static HRESULT WINAPI
DOMKeyboardEvent_GetIDsOfNames(IDOMKeyboardEvent
*iface
, REFIID riid
,
1814 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1816 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1817 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1821 static HRESULT WINAPI
DOMKeyboardEvent_Invoke(IDOMKeyboardEvent
*iface
, DISPID dispIdMember
,
1822 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1823 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1825 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1826 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1827 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1830 static HRESULT WINAPI
DOMKeyboardEvent_get_key(IDOMKeyboardEvent
*iface
, BSTR
*p
)
1832 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1836 TRACE("(%p)->(%p)\n", This
, p
);
1839 nsAString_Init(&key_str
, NULL
);
1840 nsres
= nsIDOMKeyEvent_GetKey(This
->keyboard_event
, &key_str
);
1841 return return_nsstr(nsres
, &key_str
, p
);
1844 static HRESULT WINAPI
DOMKeyboardEvent_get_location(IDOMKeyboardEvent
*iface
, ULONG
*p
)
1846 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1850 TRACE("(%p)->(%p)\n", This
, p
);
1852 nsres
= nsIDOMKeyEvent_GetLocation(This
->keyboard_event
, &r
);
1853 if(NS_FAILED(nsres
))
1860 static HRESULT WINAPI
DOMKeyboardEvent_get_ctrlKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1862 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1866 TRACE("(%p)->(%p)\n", This
, p
);
1868 nsres
= nsIDOMKeyEvent_GetCtrlKey(This
->keyboard_event
, &r
);
1869 if(NS_FAILED(nsres
))
1872 *p
= variant_bool(r
);
1876 static HRESULT WINAPI
DOMKeyboardEvent_get_shiftKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1878 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1882 TRACE("(%p)->(%p)\n", This
, p
);
1884 nsres
= nsIDOMKeyEvent_GetShiftKey(This
->keyboard_event
, &r
);
1885 if(NS_FAILED(nsres
))
1888 *p
= variant_bool(r
);
1892 static HRESULT WINAPI
DOMKeyboardEvent_get_altKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1894 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1898 TRACE("(%p)->(%p)\n", This
, p
);
1900 nsres
= nsIDOMKeyEvent_GetAltKey(This
->keyboard_event
, &r
);
1901 if(NS_FAILED(nsres
))
1904 *p
= variant_bool(r
);
1908 static HRESULT WINAPI
DOMKeyboardEvent_get_metaKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1910 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1914 TRACE("(%p)->(%p)\n", This
, p
);
1916 nsres
= nsIDOMKeyEvent_GetMetaKey(This
->keyboard_event
, &r
);
1917 if(NS_FAILED(nsres
))
1920 *p
= variant_bool(r
);
1924 static HRESULT WINAPI
DOMKeyboardEvent_get_repeat(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
1926 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1930 TRACE("(%p)->(%p)\n", This
, p
);
1932 nsres
= nsIDOMKeyEvent_GetRepeat(This
->keyboard_event
, &r
);
1933 if(NS_FAILED(nsres
))
1936 *p
= variant_bool(r
);
1940 static HRESULT WINAPI
DOMKeyboardEvent_getModifierState(IDOMKeyboardEvent
*iface
, BSTR key
,
1941 VARIANT_BOOL
*state
)
1943 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1944 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(key
), state
);
1948 static HRESULT WINAPI
DOMKeyboardEvent_initKeyboardEvent(IDOMKeyboardEvent
*iface
, BSTR type
,
1949 VARIANT_BOOL can_bubble
, VARIANT_BOOL cancelable
, IHTMLWindow2
*view
, BSTR key
,
1950 ULONG location
, BSTR modifiers_list
, VARIANT_BOOL repeat
, BSTR locale
)
1952 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1953 FIXME("(%p)->(%s %x %x %p %s %u %s %x %s)\n", This
, debugstr_w(type
), can_bubble
,
1954 cancelable
, view
, debugstr_w(key
), location
, debugstr_w(modifiers_list
),
1955 repeat
, debugstr_w(locale
));
1959 static HRESULT WINAPI
DOMKeyboardEvent_get_keyCode(IDOMKeyboardEvent
*iface
, LONG
*p
)
1961 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1965 TRACE("(%p)->(%p)\n", This
, p
);
1967 nsres
= nsIDOMKeyEvent_GetKeyCode(This
->keyboard_event
, &r
);
1968 if(NS_FAILED(nsres
))
1975 static HRESULT WINAPI
DOMKeyboardEvent_get_charCode(IDOMKeyboardEvent
*iface
, LONG
*p
)
1977 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1981 TRACE("(%p)->(%p)\n", This
, p
);
1983 nsres
= nsIDOMKeyEvent_GetKeyCode(This
->keyboard_event
, &r
);
1984 if(NS_FAILED(nsres
))
1991 static HRESULT WINAPI
DOMKeyboardEvent_get_which(IDOMKeyboardEvent
*iface
, LONG
*p
)
1993 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1997 TRACE("(%p)->(%p)\n", This
, p
);
1999 nsres
= nsIDOMKeyEvent_GetWhich(This
->keyboard_event
, &r
);
2000 if(NS_FAILED(nsres
))
2007 static HRESULT WINAPI
DOMKeyboardEvent_get_char(IDOMKeyboardEvent
*iface
, VARIANT
*p
)
2009 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2010 FIXME("(%p)->(%p)\n", This
, p
);
2014 static HRESULT WINAPI
DOMKeyboardEvent_get_locale(IDOMKeyboardEvent
*iface
, BSTR
*p
)
2016 DOMEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2017 FIXME("(%p)->(%p)\n", This
, p
);
2021 static const IDOMKeyboardEventVtbl DOMKeyboardEventVtbl
= {
2022 DOMKeyboardEvent_QueryInterface
,
2023 DOMKeyboardEvent_AddRef
,
2024 DOMKeyboardEvent_Release
,
2025 DOMKeyboardEvent_GetTypeInfoCount
,
2026 DOMKeyboardEvent_GetTypeInfo
,
2027 DOMKeyboardEvent_GetIDsOfNames
,
2028 DOMKeyboardEvent_Invoke
,
2029 DOMKeyboardEvent_get_key
,
2030 DOMKeyboardEvent_get_location
,
2031 DOMKeyboardEvent_get_ctrlKey
,
2032 DOMKeyboardEvent_get_shiftKey
,
2033 DOMKeyboardEvent_get_altKey
,
2034 DOMKeyboardEvent_get_metaKey
,
2035 DOMKeyboardEvent_get_repeat
,
2036 DOMKeyboardEvent_getModifierState
,
2037 DOMKeyboardEvent_initKeyboardEvent
,
2038 DOMKeyboardEvent_get_keyCode
,
2039 DOMKeyboardEvent_get_charCode
,
2040 DOMKeyboardEvent_get_which
,
2041 DOMKeyboardEvent_get_char
,
2042 DOMKeyboardEvent_get_locale
2045 static const tid_t DOMEvent_iface_tids
[] = {
2050 static dispex_static_data_t DOMEvent_dispex
= {
2056 static const tid_t DOMUIEvent_iface_tids
[] = {
2062 static dispex_static_data_t DOMUIEvent_dispex
= {
2065 DOMUIEvent_iface_tids
2068 static const tid_t DOMMouseEvent_iface_tids
[] = {
2075 static dispex_static_data_t DOMMouseEvent_dispex
= {
2077 DispDOMMouseEvent_tid
,
2078 DOMMouseEvent_iface_tids
2081 static const tid_t DOMKeyboardEvent_iface_tids
[] = {
2084 IDOMKeyboardEvent_tid
,
2088 static dispex_static_data_t DOMKeyboardEvent_dispex
= {
2090 DispDOMKeyboardEvent_tid
,
2091 DOMKeyboardEvent_iface_tids
2094 static DOMEvent
*alloc_event(nsIDOMEvent
*nsevent
, eventid_t event_id
)
2096 dispex_static_data_t
*dispex_data
= &DOMEvent_dispex
;
2101 /* 1601 to 1970 is 369 years plus 89 leap days */
2102 const ULONGLONG time_epoch
= (ULONGLONG
)(369 * 365 + 89) * 86400 * 1000;
2104 event
= heap_alloc_zero(sizeof(*event
));
2108 event
->IDOMEvent_iface
.lpVtbl
= &DOMEventVtbl
;
2109 event
->IDOMUIEvent_iface
.lpVtbl
= &DOMUIEventVtbl
;
2110 event
->IDOMMouseEvent_iface
.lpVtbl
= &DOMMouseEventVtbl
;
2111 event
->IDOMKeyboardEvent_iface
.lpVtbl
= &DOMKeyboardEventVtbl
;
2113 event
->event_id
= event_id
;
2114 if(event_id
!= EVENTID_LAST
) {
2115 event
->type
= heap_strdupW(event_info
[event_id
].name
);
2120 event
->bubbles
= (event_info
[event_id
].flags
& EVENT_BUBBLES
) != 0;
2121 event
->cancelable
= (event_info
[event_id
].flags
& EVENT_CANCELABLE
) != 0;
2123 nsIDOMEvent_AddRef(event
->nsevent
= nsevent
);
2125 GetSystemTimeAsFileTime(&time
);
2126 event
->time_stamp
= (((ULONGLONG
)time
.dwHighDateTime
<<32) + time
.dwLowDateTime
) / 10000
2129 nsres
= nsIDOMEvent_QueryInterface(nsevent
, &IID_nsIDOMUIEvent
, (void**)&event
->ui_event
);
2130 if(NS_SUCCEEDED(nsres
))
2131 dispex_data
= &DOMUIEvent_dispex
;
2133 event
->ui_event
= NULL
;
2135 nsres
= nsIDOMEvent_QueryInterface(nsevent
, &IID_nsIDOMMouseEvent
, (void**)&event
->mouse_event
);
2136 if(NS_SUCCEEDED(nsres
))
2137 dispex_data
= &DOMMouseEvent_dispex
;
2139 event
->mouse_event
= NULL
;
2141 nsres
= nsIDOMEvent_QueryInterface(nsevent
, &IID_nsIDOMKeyEvent
, (void**)&event
->keyboard_event
);
2142 if(NS_SUCCEEDED(nsres
))
2143 dispex_data
= &DOMKeyboardEvent_dispex
;
2145 event
->keyboard_event
= NULL
;
2147 init_dispex(&event
->dispex
, (IUnknown
*)&event
->IDOMEvent_iface
, dispex_data
);
2151 HRESULT
create_event_from_nsevent(nsIDOMEvent
*nsevent
, DOMEvent
**ret_event
)
2153 eventid_t event_id
= EVENTID_LAST
;
2158 nsAString_Init(&nsstr
, NULL
);
2159 nsres
= nsIDOMEvent_GetType(nsevent
, &nsstr
);
2160 if(NS_SUCCEEDED(nsres
)) {
2162 nsAString_GetData(&nsstr
, &type
);
2163 event_id
= str_to_eid(type
);
2164 if(event_id
== EVENTID_LAST
)
2165 FIXME("unknown event type %s\n", debugstr_w(type
));
2167 ERR("GetType failed: %08x\n", nsres
);
2169 nsAString_Finish(&nsstr
);
2171 event
= alloc_event(nsevent
, event_id
);
2173 return E_OUTOFMEMORY
;
2179 HRESULT
create_document_event_str(HTMLDocumentNode
*doc
, const WCHAR
*type
, IDOMEvent
**ret_event
)
2181 nsIDOMEvent
*nsevent
;
2186 nsAString_InitDepend(&nsstr
, type
);
2187 nsres
= nsIDOMHTMLDocument_CreateEvent(doc
->nsdoc
, &nsstr
, &nsevent
);
2188 nsAString_Finish(&nsstr
);
2189 if(NS_FAILED(nsres
)) {
2190 FIXME("CreateEvent(%s) failed: %08x\n", debugstr_w(type
), nsres
);
2194 event
= alloc_event(nsevent
, EVENTID_LAST
);
2195 nsIDOMEvent_Release(nsevent
);
2197 return E_OUTOFMEMORY
;
2199 *ret_event
= &event
->IDOMEvent_iface
;
2203 HRESULT
create_document_event(HTMLDocumentNode
*doc
, eventid_t event_id
, DOMEvent
**ret_event
)
2205 nsIDOMEvent
*nsevent
;
2210 nsAString_InitDepend(&nsstr
, event_types
[event_info
[event_id
].type
]);
2211 nsres
= nsIDOMHTMLDocument_CreateEvent(doc
->nsdoc
, &nsstr
, &nsevent
);
2212 nsAString_Finish(&nsstr
);
2213 if(NS_FAILED(nsres
)) {
2214 FIXME("CreateEvent(%s) failed: %08x\n", debugstr_w(event_types
[event_info
[event_id
].type
]), nsres
);
2218 event
= alloc_event(nsevent
, event_id
);
2220 return E_OUTOFMEMORY
;
2222 event
->event_id
= event_id
;
2227 static HRESULT
call_disp_func(IDispatch
*disp
, DISPPARAMS
*dp
, VARIANT
*retv
)
2229 IDispatchEx
*dispex
;
2233 memset(&ei
, 0, sizeof(ei
));
2235 hres
= IDispatch_QueryInterface(disp
, &IID_IDispatchEx
, (void**)&dispex
);
2236 if(SUCCEEDED(hres
)) {
2237 hres
= IDispatchEx_InvokeEx(dispex
, 0, GetUserDefaultLCID(), DISPATCH_METHOD
, dp
, retv
, &ei
, NULL
);
2238 IDispatchEx_Release(dispex
);
2240 TRACE("Could not get IDispatchEx interface: %08x\n", hres
);
2241 hres
= IDispatch_Invoke(disp
, 0, &IID_NULL
, GetUserDefaultLCID(), DISPATCH_METHOD
,
2242 dp
, retv
, &ei
, NULL
);
2248 static HRESULT
call_cp_func(IDispatch
*disp
, DISPID dispid
, IHTMLEventObj
*event_obj
, VARIANT
*retv
)
2250 DISPPARAMS dp
= {NULL
,NULL
,0,0};
2256 V_VT(&event_arg
) = VT_DISPATCH
;
2257 V_DISPATCH(&event_arg
) = (IDispatch
*)event_obj
;
2258 dp
.rgvarg
= &event_arg
;
2262 memset(&ei
, 0, sizeof(ei
));
2263 return IDispatch_Invoke(disp
, dispid
, &IID_NULL
, 0, DISPATCH_METHOD
, &dp
, retv
, &ei
, &argerr
);
2266 static BOOL
use_event_quirks(EventTarget
*event_target
)
2268 return dispex_compat_mode(&event_target
->dispex
) < COMPAT_MODE_IE9
;
2271 static BOOL
is_cp_event(cp_static_data_t
*data
, DISPID dispid
)
2276 if(!data
|| dispid
== DISPID_UNKNOWN
)
2280 hres
= get_dispids(data
->tid
, &data
->id_cnt
, &data
->ids
);
2286 max
= data
->id_cnt
-1;
2289 if(data
->ids
[i
] == dispid
)
2292 if(data
->ids
[i
] < dispid
)
2301 static void call_event_handlers(EventTarget
*event_target
, DOMEvent
*event
, dispatch_mode_t dispatch_mode
)
2303 const listener_container_t
*container
= get_listener_container(event_target
, event
->type
, FALSE
);
2304 const BOOL use_quirks
= use_event_quirks(event_target
);
2305 event_listener_t
*listener
, listeners_buf
[8], *listeners
= listeners_buf
;
2306 unsigned listeners_cnt
, listeners_size
;
2307 ConnectionPointContainer
*cp_container
= NULL
;
2308 const event_target_vtbl_t
*vtbl
= NULL
;
2312 assert(!event
->current_target
);
2313 event
->current_target
= event_target
;
2315 if(use_quirks
&& container
&& !list_empty(&container
->listeners
)
2316 && event
->phase
!= DEP_CAPTURING_PHASE
) {
2317 listener
= LIST_ENTRY(list_tail(&container
->listeners
), event_listener_t
, entry
);
2318 if(listener
&& listener
->function
&& listener
->type
== LISTENER_TYPE_ONEVENT
) {
2319 DISPID named_arg
= DISPID_THIS
;
2321 DISPPARAMS dp
= {&arg
, &named_arg
, 1, 1};
2323 V_VT(&arg
) = VT_DISPATCH
;
2324 V_DISPATCH(&arg
) = (IDispatch
*)&event_target
->dispex
.IDispatchEx_iface
;
2325 V_VT(&v
) = VT_EMPTY
;
2327 TRACE("%s >>>\n", debugstr_w(event
->type
));
2328 hres
= call_disp_func(listener
->function
, &dp
, &v
);
2330 TRACE("%s <<< %s\n", debugstr_w(event
->type
), debugstr_variant(&v
));
2332 if(event
->cancelable
) {
2333 if(V_VT(&v
) == VT_BOOL
) {
2335 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
2336 }else if(V_VT(&v
) != VT_EMPTY
) {
2337 FIXME("unhandled result %s\n", debugstr_variant(&v
));
2342 WARN("%s <<< %08x\n", debugstr_w(event
->type
), hres
);
2348 listeners_size
= sizeof(listeners_buf
)/sizeof(*listeners_buf
);
2351 LIST_FOR_EACH_ENTRY(listener
, &container
->listeners
, event_listener_t
, entry
) {
2352 if(!listener
->function
)
2354 switch(listener
->type
) {
2355 case LISTENER_TYPE_ONEVENT
:
2356 if(use_quirks
|| event
->phase
== DEP_CAPTURING_PHASE
)
2359 case LISTENER_TYPE_CAPTURE
:
2360 if(event
->phase
== DEP_BUBBLING_PHASE
|| dispatch_mode
== DISPATCH_LEGACY
)
2363 case LISTENER_TYPE_BUBBLE
:
2364 if(event
->phase
== DEP_CAPTURING_PHASE
|| dispatch_mode
== DISPATCH_LEGACY
)
2367 case LISTENER_TYPE_ATTACHED
:
2368 if(event
->phase
== DEP_CAPTURING_PHASE
|| dispatch_mode
== DISPATCH_STANDARD
)
2373 if(listeners_cnt
== listeners_size
) {
2374 event_listener_t
*new_listeners
;
2375 if(listeners
== listeners_buf
) {
2376 new_listeners
= heap_alloc(listeners_size
* 2 * sizeof(*new_listeners
));
2379 memcpy(new_listeners
, listeners
, listeners_cnt
* sizeof(*listeners
));
2381 new_listeners
= heap_realloc(listeners
, listeners_size
* 2 * sizeof(*new_listeners
));
2383 listeners
= new_listeners
;
2384 listeners_size
*= 2;
2387 listeners
[listeners_cnt
].type
= listener
->type
;
2388 IDispatch_AddRef(listeners
[listeners_cnt
].function
= listener
->function
);
2393 for(listener
= listeners
; !event
->stop_immediate_propagation
2394 && listener
< listeners
+ listeners_cnt
; listener
++) {
2395 if(listener
->type
!= LISTENER_TYPE_ATTACHED
) {
2396 DISPID named_arg
= DISPID_THIS
;
2398 DISPPARAMS dp
= {args
, &named_arg
, 2, 1};
2400 V_VT(args
) = VT_DISPATCH
;
2401 V_DISPATCH(args
) = (IDispatch
*)&event_target
->dispex
.IDispatchEx_iface
;
2402 V_VT(args
+1) = VT_DISPATCH
;
2403 V_DISPATCH(args
+1) = dispatch_mode
== DISPATCH_LEGACY
2404 ? (IDispatch
*)event
->event_obj
: (IDispatch
*)&event
->IDOMEvent_iface
;
2405 V_VT(&v
) = VT_EMPTY
;
2407 TRACE("%s >>>\n", debugstr_w(event
->type
));
2408 hres
= call_disp_func(listener
->function
, &dp
, &v
);
2410 TRACE("%s <<< %s\n", debugstr_w(event
->type
),
2411 debugstr_variant(&v
));
2413 if(event
->cancelable
) {
2414 if(V_VT(&v
) == VT_BOOL
) {
2416 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
2417 }else if(V_VT(&v
) != VT_EMPTY
) {
2418 FIXME("unhandled result %s\n", debugstr_variant(&v
));
2423 WARN("%s <<< %08x\n", debugstr_w(event
->type
), hres
);
2427 DISPPARAMS dp
= {&arg
, NULL
, 1, 0};
2429 V_VT(&arg
) = VT_DISPATCH
;
2430 V_DISPATCH(&arg
) = (IDispatch
*)event
->event_obj
;
2431 V_VT(&v
) = VT_EMPTY
;
2433 TRACE("%s attached >>>\n", debugstr_w(event
->type
));
2434 hres
= call_disp_func(listener
->function
, &dp
, &v
);
2436 TRACE("%s attached <<<\n", debugstr_w(event
->type
));
2438 if(event
->cancelable
) {
2439 if(V_VT(&v
) == VT_BOOL
) {
2441 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
2442 }else if(V_VT(&v
) != VT_EMPTY
) {
2443 FIXME("unhandled result %s\n", debugstr_variant(&v
));
2448 WARN("%s attached <<< %08x\n", debugstr_w(event
->type
), hres
);
2453 for(listener
= listeners
; listener
< listeners
+ listeners_cnt
; listener
++)
2454 IDispatch_Release(listener
->function
);
2455 if(listeners
!= listeners_buf
)
2456 heap_free(listeners
);
2458 if(event
->phase
!= DEP_CAPTURING_PHASE
&& event
->event_id
!= EVENTID_LAST
2459 && event_info
[event
->event_id
].dispid
&& (vtbl
= dispex_get_vtbl(&event_target
->dispex
))
2460 && vtbl
->get_cp_container
)
2461 cp_container
= vtbl
->get_cp_container(&event_target
->dispex
);
2463 if(cp_container
->cps
) {
2464 ConnectionPoint
*cp
;
2467 for(j
=0; cp_container
->cp_entries
[j
].riid
; j
++) {
2468 cp
= cp_container
->cps
+ j
;
2469 if(!cp
->sinks_size
|| !is_cp_event(cp
->data
, event_info
[event
->event_id
].dispid
))
2472 for(i
=0; i
< cp
->sinks_size
; i
++) {
2473 if(!cp
->sinks
[i
].disp
)
2476 V_VT(&v
) = VT_EMPTY
;
2478 TRACE("cp %s [%u] >>>\n", debugstr_w(event
->type
), i
);
2479 hres
= call_cp_func(cp
->sinks
[i
].disp
, event_info
[event
->event_id
].dispid
,
2480 cp
->data
->pass_event_arg
? event
->event_obj
: NULL
, &v
);
2482 TRACE("cp %s [%u] <<<\n", debugstr_w(event
->type
), i
);
2484 if(event
->cancelable
) {
2485 if(V_VT(&v
) == VT_BOOL
) {
2487 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
2488 }else if(V_VT(&v
) != VT_EMPTY
) {
2489 FIXME("unhandled result %s\n", debugstr_variant(&v
));
2494 WARN("cp %s [%u] <<< %08x\n", debugstr_w(event
->type
), i
, hres
);
2499 IConnectionPointContainer_Release(&cp_container
->IConnectionPointContainer_iface
);
2502 event
->current_target
= NULL
;
2505 static HRESULT
dispatch_event_object(EventTarget
*event_target
, DOMEvent
*event
,
2506 dispatch_mode_t dispatch_mode
, VARIANT_BOOL
*r
)
2508 EventTarget
*target_chain_buf
[8], **target_chain
= target_chain_buf
;
2509 unsigned chain_cnt
, chain_buf_size
, i
;
2510 const event_target_vtbl_t
*vtbl
, *target_vtbl
;
2511 HTMLEventObj
*event_obj_ref
= NULL
;
2512 IHTMLEventObj
*prev_event
= NULL
;
2516 TRACE("(%p) %s\n", event_target
, debugstr_w(event
->type
));
2519 FIXME("Uninitialized event.\n");
2523 if(event
->current_target
) {
2524 FIXME("event is being dispatched.\n");
2528 iter
= event_target
;
2529 IEventTarget_AddRef(&event_target
->IEventTarget_iface
);
2532 chain_buf_size
= sizeof(target_chain_buf
)/sizeof(*target_chain_buf
);
2535 if(chain_cnt
== chain_buf_size
) {
2536 EventTarget
**new_chain
;
2537 if(target_chain
== target_chain_buf
) {
2538 new_chain
= heap_alloc(chain_buf_size
* 2 * sizeof(*new_chain
));
2541 memcpy(new_chain
, target_chain
, chain_buf_size
* sizeof(*new_chain
));
2543 new_chain
= heap_realloc(target_chain
, chain_buf_size
* 2 * sizeof(*new_chain
));
2547 chain_buf_size
*= 2;
2548 target_chain
= new_chain
;
2551 target_chain
[chain_cnt
++] = iter
;
2553 if(!(vtbl
= dispex_get_vtbl(&iter
->dispex
)) || !vtbl
->get_parent_event_target
)
2555 iter
= vtbl
->get_parent_event_target(&iter
->dispex
);
2558 if(!event
->event_obj
&& !event
->no_event_obj
) {
2559 event_obj_ref
= alloc_event_obj(event
);
2561 event
->event_obj
= &event_obj_ref
->IHTMLEventObj_iface
;
2564 target_vtbl
= dispex_get_vtbl(&event_target
->dispex
);
2565 if(target_vtbl
&& target_vtbl
->set_current_event
)
2566 prev_event
= target_vtbl
->set_current_event(&event_target
->dispex
, event
->event_obj
);
2569 IEventTarget_Release(&event
->target
->IEventTarget_iface
);
2570 event
->target
= event_target
;
2571 IEventTarget_AddRef(&event_target
->IEventTarget_iface
);
2573 event
->phase
= DEP_CAPTURING_PHASE
;
2575 while(!event
->stop_propagation
&& i
)
2576 call_event_handlers(target_chain
[i
--], event
, dispatch_mode
);
2578 if(!event
->stop_propagation
) {
2579 event
->phase
= DEP_AT_TARGET
;
2580 call_event_handlers(target_chain
[0], event
, dispatch_mode
);
2583 if(event
->bubbles
) {
2584 event
->phase
= DEP_BUBBLING_PHASE
;
2585 for(i
= 1; !event
->stop_propagation
&& i
< chain_cnt
; i
++)
2586 call_event_handlers(target_chain
[i
], event
, dispatch_mode
);
2590 *r
= variant_bool(!event
->prevent_default
);
2592 if(target_vtbl
&& target_vtbl
->set_current_event
) {
2593 prev_event
= target_vtbl
->set_current_event(&event_target
->dispex
, prev_event
);
2595 IHTMLEventObj_Release(prev_event
);
2598 if(event
->event_id
!= EVENTID_LAST
&& (event_info
[event
->event_id
].flags
& EVENT_HASDEFAULTHANDLERS
)) {
2599 BOOL prevent_default
= event
->prevent_default
;
2600 for(i
= 0; !prevent_default
&& i
< chain_cnt
; i
++) {
2601 vtbl
= dispex_get_vtbl(&target_chain
[i
]->dispex
);
2602 if(!vtbl
|| !vtbl
->handle_event_default
)
2604 hres
= vtbl
->handle_event_default(&event_target
->dispex
, event
->event_id
,
2605 event
->nsevent
, &prevent_default
);
2606 if(FAILED(hres
) || event
->stop_propagation
)
2609 nsIDOMEvent_PreventDefault(event
->nsevent
);
2613 event
->prevent_default
= FALSE
;
2615 event
->event_obj
= NULL
;
2616 IHTMLEventObj_Release(&event_obj_ref
->IHTMLEventObj_iface
);
2619 for(i
= 0; i
< chain_cnt
; i
++)
2620 IEventTarget_Release(&target_chain
[i
]->IEventTarget_iface
);
2621 if(target_chain
!= target_chain_buf
)
2622 heap_free(target_chain
);
2627 void dispatch_event(EventTarget
*event_target
, DOMEvent
*event
)
2629 dispatch_event_object(event_target
, event
, DISPATCH_BOTH
, NULL
);
2632 * We may have registered multiple Gecko listeners for the same event type,
2633 * but we already dispatched event to all relevant targets. Stop event
2634 * propagation here to avoid events being dispatched multiple times.
2636 if(event
->event_id
!= EVENTID_LAST
&& (event_info
[event
->event_id
].flags
& EVENT_BIND_TO_TARGET
))
2637 nsIDOMEvent_StopPropagation(event
->nsevent
);
2640 HRESULT
fire_event(HTMLDOMNode
*node
, const WCHAR
*event_name
, VARIANT
*event_var
, VARIANT_BOOL
*cancelled
)
2642 HTMLEventObj
*event_obj
= NULL
;
2644 HRESULT hres
= S_OK
;
2646 eid
= attr_to_eid(event_name
);
2647 if(eid
== EVENTID_LAST
) {
2648 WARN("unknown event %s\n", debugstr_w(event_name
));
2649 return E_INVALIDARG
;
2652 if(event_var
&& V_VT(event_var
) != VT_EMPTY
&& V_VT(event_var
) != VT_ERROR
) {
2653 if(V_VT(event_var
) != VT_DISPATCH
) {
2654 FIXME("event_var %s not supported\n", debugstr_variant(event_var
));
2658 if(V_DISPATCH(event_var
)) {
2659 IHTMLEventObj
*event_iface
;
2661 hres
= IDispatch_QueryInterface(V_DISPATCH(event_var
), &IID_IHTMLEventObj
, (void**)&event_iface
);
2663 FIXME("No IHTMLEventObj iface\n");
2667 event_obj
= unsafe_impl_from_IHTMLEventObj(event_iface
);
2669 ERR("Not our IHTMLEventObj?\n");
2670 IHTMLEventObj_Release(event_iface
);
2677 event_obj
= alloc_event_obj(NULL
);
2679 return E_OUTOFMEMORY
;
2682 if(!event_obj
->event
)
2683 hres
= create_document_event(node
->doc
, eid
, &event_obj
->event
);
2685 if(SUCCEEDED(hres
)) {
2686 event_obj
->event
->event_obj
= &event_obj
->IHTMLEventObj_iface
;
2687 dispatch_event_object(&node
->event_target
, event_obj
->event
, DISPATCH_LEGACY
, NULL
);
2688 event_obj
->event
->event_obj
= NULL
;
2691 IHTMLEventObj_Release(&event_obj
->IHTMLEventObj_iface
);
2695 *cancelled
= VARIANT_TRUE
; /* FIXME */
2699 HRESULT
ensure_doc_nsevent_handler(HTMLDocumentNode
*doc
, nsIDOMNode
*nsnode
, eventid_t eid
)
2701 TRACE("%s\n", debugstr_w(event_info
[eid
].name
));
2707 case EVENTID_FOCUSIN
:
2708 doc
->event_vector
[eid
] = TRUE
;
2709 eid
= EVENTID_FOCUS
;
2711 case EVENTID_FOCUSOUT
:
2712 doc
->event_vector
[eid
] = TRUE
;
2719 if(event_info
[eid
].flags
& EVENT_DEFAULTLISTENER
) {
2721 }else if(event_info
[eid
].flags
& EVENT_BIND_TO_TARGET
) {
2723 nsnode
= doc
->node
.nsnode
;
2728 if(!nsnode
|| nsnode
== doc
->node
.nsnode
) {
2729 if(doc
->event_vector
[eid
])
2731 doc
->event_vector
[eid
] = TRUE
;
2734 add_nsevent_listener(doc
, nsnode
, event_info
[eid
].name
);
2738 void detach_events(HTMLDocumentNode
*doc
)
2740 if(doc
->event_vector
) {
2743 for(i
=0; i
< EVENTID_LAST
; i
++) {
2744 if(doc
->event_vector
[i
]) {
2745 detach_nsevent(doc
, event_info
[i
].name
);
2746 doc
->event_vector
[i
] = FALSE
;
2751 release_nsevents(doc
);
2754 static HRESULT
get_event_dispex_ref(EventTarget
*event_target
, eventid_t eid
, BOOL alloc
, VARIANT
**ret
)
2759 strcpyW(buf
+2, event_info
[eid
].name
);
2760 return dispex_get_dprop_ref(&event_target
->dispex
, buf
, alloc
, ret
);
2763 static event_listener_t
*get_onevent_listener(EventTarget
*event_target
, eventid_t eid
, BOOL alloc
)
2765 listener_container_t
*container
;
2766 event_listener_t
*listener
;
2768 container
= get_listener_container(event_target
, event_info
[eid
].name
, alloc
);
2772 LIST_FOR_EACH_ENTRY_REV(listener
, &container
->listeners
, event_listener_t
, entry
) {
2773 if(listener
->type
== LISTENER_TYPE_ONEVENT
)
2780 listener
= heap_alloc(sizeof(*listener
));
2784 listener
->type
= LISTENER_TYPE_ONEVENT
;
2785 listener
->function
= NULL
;
2786 list_add_tail(&container
->listeners
, &listener
->entry
);
2790 static void remove_event_handler(EventTarget
*event_target
, eventid_t eid
)
2792 event_listener_t
*listener
;
2796 hres
= get_event_dispex_ref(event_target
, eid
, FALSE
, &store
);
2798 VariantClear(store
);
2800 listener
= get_onevent_listener(event_target
, eid
, FALSE
);
2801 if(listener
&& listener
->function
) {
2802 IDispatch_Release(listener
->function
);
2803 listener
->function
= NULL
;
2807 static HRESULT
set_event_handler_disp(EventTarget
*event_target
, eventid_t eid
, IDispatch
*disp
)
2809 event_listener_t
*listener
;
2811 if(event_info
[eid
].flags
& EVENT_FIXME
)
2812 FIXME("unimplemented event %s\n", debugstr_w(event_info
[eid
].name
));
2814 remove_event_handler(event_target
, eid
);
2818 listener
= get_onevent_listener(event_target
, eid
, TRUE
);
2820 return E_OUTOFMEMORY
;
2822 if(listener
->function
)
2823 IDispatch_Release(listener
->function
);
2825 IDispatch_AddRef(listener
->function
= disp
);
2829 HRESULT
set_event_handler(EventTarget
*event_target
, eventid_t eid
, VARIANT
*var
)
2833 if(use_event_quirks(event_target
)) {
2834 WARN("attempt to set to VT_EMPTY in quirks mode\n");
2839 remove_event_handler(event_target
, eid
);
2843 return set_event_handler_disp(event_target
, eid
, V_DISPATCH(var
));
2849 if(!use_event_quirks(event_target
))
2850 FIXME("Setting to string %s not supported\n", debugstr_w(V_BSTR(var
)));
2853 * Setting event handler to string is a rare case and we don't want to
2854 * complicate nor increase memory of listener_container_t for that. Instead,
2855 * we store the value in DispatchEx, which can already handle custom
2858 remove_event_handler(event_target
, eid
);
2860 hres
= get_event_dispex_ref(event_target
, eid
, TRUE
, &v
);
2864 V_BSTR(v
) = SysAllocString(V_BSTR(var
));
2866 return E_OUTOFMEMORY
;
2872 FIXME("not handler %s\n", debugstr_variant(var
));
2879 HRESULT
get_event_handler(EventTarget
*event_target
, eventid_t eid
, VARIANT
*var
)
2881 event_listener_t
*listener
;
2885 hres
= get_event_dispex_ref(event_target
, eid
, FALSE
, &v
);
2886 if(SUCCEEDED(hres
) && V_VT(v
) != VT_EMPTY
) {
2887 V_VT(var
) = VT_EMPTY
;
2888 return VariantCopy(var
, v
);
2891 listener
= get_onevent_listener(event_target
, eid
, FALSE
);
2892 if(listener
&& listener
->function
) {
2893 V_VT(var
) = VT_DISPATCH
;
2894 V_DISPATCH(var
) = listener
->function
;
2895 IDispatch_AddRef(V_DISPATCH(var
));
2897 V_VT(var
) = VT_NULL
;
2903 HRESULT
attach_event(EventTarget
*event_target
, BSTR name
, IDispatch
*disp
, VARIANT_BOOL
*res
)
2905 listener_container_t
*container
;
2906 event_listener_t
*listener
;
2909 eid
= attr_to_eid(name
);
2910 if(eid
== EVENTID_LAST
) {
2911 WARN("Unknown event\n");
2912 *res
= VARIANT_TRUE
;
2916 container
= get_listener_container(event_target
, event_info
[eid
].name
, TRUE
);
2918 return E_OUTOFMEMORY
;
2920 listener
= heap_alloc(sizeof(*listener
));
2922 return E_OUTOFMEMORY
;
2924 listener
->type
= LISTENER_TYPE_ATTACHED
;
2925 IDispatch_AddRef(listener
->function
= disp
);
2926 if(use_event_quirks(event_target
))
2927 list_add_head(&container
->listeners
, &listener
->entry
);
2929 list_add_tail(&container
->listeners
, &listener
->entry
);
2931 *res
= VARIANT_TRUE
;
2935 HRESULT
detach_event(EventTarget
*event_target
, BSTR name
, IDispatch
*disp
)
2939 eid
= attr_to_eid(name
);
2940 if(eid
== EVENTID_LAST
) {
2941 WARN("Unknown event\n");
2945 remove_event_listener(event_target
, event_info
[eid
].name
, LISTENER_TYPE_ATTACHED
, disp
);
2949 void bind_target_event(HTMLDocumentNode
*doc
, EventTarget
*event_target
, const WCHAR
*event
, IDispatch
*disp
)
2953 TRACE("(%p %p %s %p)\n", doc
, event_target
, debugstr_w(event
), disp
);
2955 eid
= attr_to_eid(event
);
2956 if(eid
== EVENTID_LAST
) {
2957 WARN("Unsupported event %s\n", debugstr_w(event
));
2961 set_event_handler_disp(event_target
, eid
, disp
);
2964 void update_doc_cp_events(HTMLDocumentNode
*doc
, cp_static_data_t
*cp
)
2968 for(i
=0; i
< EVENTID_LAST
; i
++) {
2969 if((event_info
[i
].flags
& EVENT_DEFAULTLISTENER
) && is_cp_event(cp
, event_info
[i
].dispid
))
2970 ensure_doc_nsevent_handler(doc
, NULL
, i
);
2974 void check_event_attr(HTMLDocumentNode
*doc
, nsIDOMElement
*nselem
)
2976 nsIDOMMozNamedAttrMap
*attr_map
;
2977 const PRUnichar
*name
, *value
;
2978 nsAString name_str
, value_str
;
2979 HTMLDOMNode
*node
= NULL
;
2988 nsres
= nsIDOMElement_HasAttributes(nselem
, &has_attrs
);
2989 if(NS_FAILED(nsres
) || !has_attrs
)
2992 nsres
= nsIDOMElement_GetAttributes(nselem
, &attr_map
);
2993 if(NS_FAILED(nsres
))
2996 nsres
= nsIDOMMozNamedAttrMap_GetLength(attr_map
, &length
);
2997 assert(nsres
== NS_OK
);
2999 nsAString_Init(&name_str
, NULL
);
3000 nsAString_Init(&value_str
, NULL
);
3002 for(i
= 0; i
< length
; i
++) {
3003 nsres
= nsIDOMMozNamedAttrMap_Item(attr_map
, i
, &attr
);
3004 if(NS_FAILED(nsres
))
3007 nsres
= nsIDOMAttr_GetName(attr
, &name_str
);
3008 if(NS_FAILED(nsres
)) {
3009 nsIDOMAttr_Release(attr
);
3013 nsAString_GetData(&name_str
, &name
);
3014 eid
= attr_to_eid(name
);
3015 if(eid
== EVENTID_LAST
) {
3016 nsIDOMAttr_Release(attr
);
3020 nsres
= nsIDOMAttr_GetValue(attr
, &value_str
);
3021 nsIDOMAttr_Release(attr
);
3022 if(NS_FAILED(nsres
))
3025 nsAString_GetData(&value_str
, &value
);
3029 TRACE("%p.%s = %s\n", nselem
, debugstr_w(name
), debugstr_w(value
));
3031 disp
= script_parse_event(doc
->window
, value
);
3036 hres
= get_node((nsIDOMNode
*)nselem
, TRUE
, &node
);
3038 IDispatch_Release(disp
);
3043 set_event_handler_disp(get_node_event_prop_target(node
, eid
), eid
, disp
);
3044 IDispatch_Release(disp
);
3049 nsAString_Finish(&name_str
);
3050 nsAString_Finish(&value_str
);
3051 nsIDOMMozNamedAttrMap_Release(attr_map
);
3054 HRESULT
doc_init_events(HTMLDocumentNode
*doc
)
3059 doc
->event_vector
= heap_alloc_zero(EVENTID_LAST
*sizeof(BOOL
));
3060 if(!doc
->event_vector
)
3061 return E_OUTOFMEMORY
;
3065 for(i
=0; i
< EVENTID_LAST
; i
++) {
3066 if(event_info
[i
].flags
& EVENT_HASDEFAULTHANDLERS
) {
3067 hres
= ensure_doc_nsevent_handler(doc
, NULL
, i
);
3076 static inline EventTarget
*impl_from_IEventTarget(IEventTarget
*iface
)
3078 return CONTAINING_RECORD(iface
, EventTarget
, IEventTarget_iface
);
3081 static HRESULT WINAPI
EventTarget_QueryInterface(IEventTarget
*iface
, REFIID riid
, void **ppv
)
3083 EventTarget
*This
= impl_from_IEventTarget(iface
);
3084 return IDispatchEx_QueryInterface(&This
->dispex
.IDispatchEx_iface
, riid
, ppv
);
3087 static ULONG WINAPI
EventTarget_AddRef(IEventTarget
*iface
)
3089 EventTarget
*This
= impl_from_IEventTarget(iface
);
3090 return IDispatchEx_AddRef(&This
->dispex
.IDispatchEx_iface
);
3093 static ULONG WINAPI
EventTarget_Release(IEventTarget
*iface
)
3095 EventTarget
*This
= impl_from_IEventTarget(iface
);
3096 return IDispatchEx_Release(&This
->dispex
.IDispatchEx_iface
);
3099 static HRESULT WINAPI
EventTarget_GetTypeInfoCount(IEventTarget
*iface
, UINT
*pctinfo
)
3101 EventTarget
*This
= impl_from_IEventTarget(iface
);
3102 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
3105 static HRESULT WINAPI
EventTarget_GetTypeInfo(IEventTarget
*iface
, UINT iTInfo
,
3106 LCID lcid
, ITypeInfo
**ppTInfo
)
3108 EventTarget
*This
= impl_from_IEventTarget(iface
);
3109 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
3112 static HRESULT WINAPI
EventTarget_GetIDsOfNames(IEventTarget
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
3113 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
3115 EventTarget
*This
= impl_from_IEventTarget(iface
);
3116 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
,
3117 rgszNames
, cNames
, lcid
, rgDispId
);
3120 static HRESULT WINAPI
EventTarget_Invoke(IEventTarget
*iface
, DISPID dispIdMember
,
3121 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
3122 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
3124 EventTarget
*This
= impl_from_IEventTarget(iface
);
3125 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
,
3126 riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
3129 static HRESULT WINAPI
EventTarget_addEventListener(IEventTarget
*iface
, BSTR type
,
3130 IDispatch
*function
, VARIANT_BOOL capture
)
3132 EventTarget
*This
= impl_from_IEventTarget(iface
);
3133 listener_type_t listener_type
= capture
? LISTENER_TYPE_CAPTURE
: LISTENER_TYPE_BUBBLE
;
3134 listener_container_t
*container
;
3135 event_listener_t
*listener
;
3137 TRACE("(%p)->(%s %p %x)\n", This
, debugstr_w(type
), function
, capture
);
3139 container
= get_listener_container(This
, type
, TRUE
);
3141 return E_OUTOFMEMORY
;
3143 /* check for duplicates */
3144 LIST_FOR_EACH_ENTRY(listener
, &container
->listeners
, event_listener_t
, entry
) {
3145 if(listener
->type
== listener_type
&& listener
->function
== function
)
3149 listener
= heap_alloc(sizeof(*listener
));
3151 return E_OUTOFMEMORY
;
3153 listener
->type
= listener_type
;
3154 IDispatch_AddRef(listener
->function
= function
);
3155 list_add_tail(&container
->listeners
, &listener
->entry
);
3159 static HRESULT WINAPI
EventTarget_removeEventListener(IEventTarget
*iface
, BSTR type
,
3160 IDispatch
*listener
, VARIANT_BOOL capture
)
3162 EventTarget
*This
= impl_from_IEventTarget(iface
);
3164 TRACE("(%p)->(%s %p %x)\n", This
, debugstr_w(type
), listener
, capture
);
3166 remove_event_listener(This
, type
, capture
? LISTENER_TYPE_CAPTURE
: LISTENER_TYPE_BUBBLE
, listener
);
3170 static HRESULT WINAPI
EventTarget_dispatchEvent(IEventTarget
*iface
, IDOMEvent
*event_iface
, VARIANT_BOOL
*result
)
3172 EventTarget
*This
= impl_from_IEventTarget(iface
);
3173 DOMEvent
*event
= unsafe_impl_from_IDOMEvent(event_iface
);
3175 TRACE("(%p)->(%p %p)\n", This
, event
, result
);
3178 WARN("Invalid event\n");
3179 return E_INVALIDARG
;
3182 return dispatch_event_object(This
, event
, DISPATCH_STANDARD
, result
);
3185 static HRESULT
IEventTarget_addEventListener_hook(DispatchEx
*dispex
, LCID lcid
, WORD flags
,
3186 DISPPARAMS
*dp
, VARIANT
*res
, EXCEPINFO
*ei
, IServiceProvider
*caller
)
3188 /* If only two arguments were given, implicitly set capture to false */
3189 if((flags
& DISPATCH_METHOD
) && dp
->cArgs
== 2 && !dp
->cNamedArgs
) {
3191 DISPPARAMS new_dp
= {args
, NULL
, 3, 0};
3192 V_VT(args
) = VT_BOOL
;
3193 V_BOOL(args
) = VARIANT_FALSE
;
3194 args
[1] = dp
->rgvarg
[0];
3195 args
[2] = dp
->rgvarg
[1];
3197 TRACE("implicit capture\n");
3199 return IDispatchEx_InvokeEx(&dispex
->IDispatchEx_iface
, DISPID_IEVENTTARGET_ADDEVENTLISTENER
,
3200 lcid
, flags
, &new_dp
, res
, ei
, caller
);
3203 return S_FALSE
; /* fallback to default */
3206 static HRESULT
IEventTarget_removeEventListener_hook(DispatchEx
*dispex
, LCID lcid
, WORD flags
,
3207 DISPPARAMS
*dp
, VARIANT
*res
, EXCEPINFO
*ei
, IServiceProvider
*caller
)
3209 /* If only two arguments were given, implicitly set capture to false */
3210 if((flags
& DISPATCH_METHOD
) && dp
->cArgs
== 2 && !dp
->cNamedArgs
) {
3212 DISPPARAMS new_dp
= {args
, NULL
, 3, 0};
3213 V_VT(args
) = VT_BOOL
;
3214 V_BOOL(args
) = VARIANT_FALSE
;
3215 args
[1] = dp
->rgvarg
[0];
3216 args
[2] = dp
->rgvarg
[1];
3218 TRACE("implicit capture\n");
3220 return IDispatchEx_InvokeEx(&dispex
->IDispatchEx_iface
, DISPID_IEVENTTARGET_REMOVEEVENTLISTENER
,
3221 lcid
, flags
, &new_dp
, res
, ei
, caller
);
3224 return S_FALSE
; /* fallback to default */
3227 static const IEventTargetVtbl EventTargetVtbl
= {
3228 EventTarget_QueryInterface
,
3230 EventTarget_Release
,
3231 EventTarget_GetTypeInfoCount
,
3232 EventTarget_GetTypeInfo
,
3233 EventTarget_GetIDsOfNames
,
3235 EventTarget_addEventListener
,
3236 EventTarget_removeEventListener
,
3237 EventTarget_dispatchEvent
3240 static EventTarget
*unsafe_impl_from_IEventTarget(IEventTarget
*iface
)
3242 return iface
&& iface
->lpVtbl
== &EventTargetVtbl
? impl_from_IEventTarget(iface
) : NULL
;
3245 static HRESULT
get_gecko_target(IEventTarget
*target
, nsIDOMEventTarget
**ret
)
3247 EventTarget
*event_target
= unsafe_impl_from_IEventTarget(target
);
3248 const event_target_vtbl_t
*vtbl
;
3252 WARN("Not our IEventTarget implementation\n");
3253 return E_INVALIDARG
;
3256 vtbl
= (const event_target_vtbl_t
*)dispex_get_vtbl(&event_target
->dispex
);
3257 nsres
= nsISupports_QueryInterface(vtbl
->get_gecko_target(&event_target
->dispex
),
3258 &IID_nsIDOMEventTarget
, (void**)ret
);
3259 assert(nsres
== NS_OK
);
3263 HRESULT
EventTarget_QI(EventTarget
*event_target
, REFIID riid
, void **ppv
)
3265 if(IsEqualGUID(riid
, &IID_IEventTarget
)) {
3266 if(use_event_quirks(event_target
)) {
3267 WARN("IEventTarget queried, but not supported by in document mode\n");
3269 return E_NOINTERFACE
;
3271 IEventTarget_AddRef(&event_target
->IEventTarget_iface
);
3272 *ppv
= &event_target
->IEventTarget_iface
;
3276 if(dispex_query_interface(&event_target
->dispex
, riid
, ppv
))
3277 return *ppv
? S_OK
: E_NOINTERFACE
;
3279 WARN("(%p)->(%s %p)\n", event_target
, debugstr_mshtml_guid(riid
), ppv
);
3281 return E_NOINTERFACE
;
3284 void EventTarget_init_dispex_info(dispex_data_t
*dispex_info
, compat_mode_t compat_mode
)
3286 static const dispex_hook_t IEventTarget_hooks
[] = {
3287 {DISPID_IEVENTTARGET_ADDEVENTLISTENER
, IEventTarget_addEventListener_hook
},
3288 {DISPID_IEVENTTARGET_REMOVEEVENTLISTENER
, IEventTarget_removeEventListener_hook
},
3292 if(compat_mode
>= COMPAT_MODE_IE9
)
3293 dispex_info_add_interface(dispex_info
, IEventTarget_tid
, IEventTarget_hooks
);
3296 static int event_id_cmp(const void *key
, const struct wine_rb_entry
*entry
)
3298 return strcmpW(key
, WINE_RB_ENTRY_VALUE(entry
, listener_container_t
, entry
)->type
);
3301 void EventTarget_Init(EventTarget
*event_target
, IUnknown
*outer
, dispex_static_data_t
*dispex_data
,
3302 compat_mode_t compat_mode
)
3304 init_dispex_with_compat_mode(&event_target
->dispex
, outer
, dispex_data
, compat_mode
);
3305 event_target
->IEventTarget_iface
.lpVtbl
= &EventTargetVtbl
;
3306 wine_rb_init(&event_target
->handler_map
, event_id_cmp
);
3309 void release_event_target(EventTarget
*event_target
)
3311 listener_container_t
*iter
, *iter2
;
3313 WINE_RB_FOR_EACH_ENTRY_DESTRUCTOR(iter
, iter2
, &event_target
->handler_map
, listener_container_t
, entry
) {
3314 while(!list_empty(&iter
->listeners
)) {
3315 event_listener_t
*listener
= LIST_ENTRY(list_head(&iter
->listeners
), event_listener_t
, entry
);
3316 if(listener
->function
)
3317 IDispatch_Release(listener
->function
);
3318 list_remove(&listener
->entry
);
3319 heap_free(listener
);