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 IEventTarget
*get_event_target_iface(EventTarget
*event_target
)
323 const event_target_vtbl_t
*vtbl
= dispex_get_vtbl(&event_target
->dispex
);
326 if(vtbl
->get_dispatch_this
) {
327 IDispatch
*disp
= vtbl
->get_dispatch_this(&event_target
->dispex
);
328 IDispatch_QueryInterface(disp
, &IID_IEventTarget
, (void**)&ret
);
330 ret
= &event_target
->IEventTarget_iface
;
331 IEventTarget_AddRef(ret
);
336 static HRESULT
get_gecko_target(IEventTarget
*,nsIDOMEventTarget
**);
340 IDOMUIEvent IDOMUIEvent_iface
;
341 nsIDOMUIEvent
*nsevent
;
344 static DOMUIEvent
*DOMUIEvent_from_DOMEvent(DOMEvent
*event
)
346 return CONTAINING_RECORD(event
, DOMUIEvent
, event
);
351 IHTMLEventObj IHTMLEventObj_iface
;
354 VARIANT return_value
;
357 static inline HTMLEventObj
*impl_from_IHTMLEventObj(IHTMLEventObj
*iface
)
359 return CONTAINING_RECORD(iface
, HTMLEventObj
, IHTMLEventObj_iface
);
362 static HRESULT WINAPI
HTMLEventObj_QueryInterface(IHTMLEventObj
*iface
, REFIID riid
, void **ppv
)
364 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
365 return IDispatchEx_QueryInterface(&This
->dispex
.IDispatchEx_iface
, riid
, ppv
);
368 static ULONG WINAPI
HTMLEventObj_AddRef(IHTMLEventObj
*iface
)
370 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
371 return IDispatchEx_AddRef(&This
->dispex
.IDispatchEx_iface
);
374 static ULONG WINAPI
HTMLEventObj_Release(IHTMLEventObj
*iface
)
376 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
377 return IDispatchEx_Release(&This
->dispex
.IDispatchEx_iface
);
380 static HRESULT WINAPI
HTMLEventObj_GetTypeInfoCount(IHTMLEventObj
*iface
, UINT
*pctinfo
)
382 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
383 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
386 static HRESULT WINAPI
HTMLEventObj_GetTypeInfo(IHTMLEventObj
*iface
, UINT iTInfo
,
387 LCID lcid
, ITypeInfo
**ppTInfo
)
389 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
390 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
393 static HRESULT WINAPI
HTMLEventObj_GetIDsOfNames(IHTMLEventObj
*iface
, REFIID riid
,
394 LPOLESTR
*rgszNames
, UINT cNames
,
395 LCID lcid
, DISPID
*rgDispId
)
397 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
398 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
402 static HRESULT WINAPI
HTMLEventObj_Invoke(IHTMLEventObj
*iface
, DISPID dispIdMember
,
403 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
404 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
406 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
407 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
408 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
411 static HRESULT WINAPI
HTMLEventObj_get_srcElement(IHTMLEventObj
*iface
, IHTMLElement
**p
)
413 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
415 TRACE("(%p)->(%p)\n", This
, p
);
422 return IDOMEvent_get_srcElement(&This
->event
->IDOMEvent_iface
, p
);
425 static HRESULT WINAPI
HTMLEventObj_get_altKey(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
427 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
428 IDOMKeyboardEvent
*keyboard_event
;
429 IDOMMouseEvent
*mouse_event
;
430 cpp_bool ret
= FALSE
;
432 TRACE("(%p)->(%p)\n", This
, p
);
434 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
435 HRESULT hres
= IDOMMouseEvent_get_altKey(mouse_event
, p
);
436 IDOMMouseEvent_Release(mouse_event
);
440 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMKeyboardEvent
, (void**)&keyboard_event
))) {
441 HRESULT hres
= IDOMKeyboardEvent_get_altKey(keyboard_event
, p
);
442 IDOMKeyboardEvent_Release(keyboard_event
);
446 *p
= variant_bool(ret
);
450 static HRESULT WINAPI
HTMLEventObj_get_ctrlKey(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
452 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
453 IDOMKeyboardEvent
*keyboard_event
;
454 IDOMMouseEvent
*mouse_event
;
455 cpp_bool ret
= FALSE
;
457 TRACE("(%p)->(%p)\n", This
, p
);
459 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
460 HRESULT hres
= IDOMMouseEvent_get_ctrlKey(mouse_event
, p
);
461 IDOMMouseEvent_Release(mouse_event
);
465 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMKeyboardEvent
, (void**)&keyboard_event
))) {
466 HRESULT hres
= IDOMKeyboardEvent_get_ctrlKey(keyboard_event
, p
);
467 IDOMKeyboardEvent_Release(keyboard_event
);
471 *p
= variant_bool(ret
);
475 static HRESULT WINAPI
HTMLEventObj_get_shiftKey(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
477 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
478 IDOMKeyboardEvent
*keyboard_event
;
479 IDOMMouseEvent
*mouse_event
;
480 cpp_bool ret
= FALSE
;
482 TRACE("(%p)->(%p)\n", This
, p
);
484 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
485 HRESULT hres
= IDOMMouseEvent_get_shiftKey(mouse_event
, p
);
486 IDOMMouseEvent_Release(mouse_event
);
490 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMKeyboardEvent
, (void**)&keyboard_event
))) {
491 HRESULT hres
= IDOMKeyboardEvent_get_shiftKey(keyboard_event
, p
);
492 IDOMKeyboardEvent_Release(keyboard_event
);
496 *p
= variant_bool(ret
);
500 static HRESULT WINAPI
HTMLEventObj_put_returnValue(IHTMLEventObj
*iface
, VARIANT v
)
502 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
504 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&v
));
506 if(V_VT(&v
) != VT_BOOL
) {
507 FIXME("unsupported value %s\n", debugstr_variant(&v
));
508 return DISP_E_BADVARTYPE
;
511 This
->return_value
= v
;
512 if(!V_BOOL(&v
) && This
->event
)
513 IDOMEvent_preventDefault(&This
->event
->IDOMEvent_iface
);
517 static HRESULT WINAPI
HTMLEventObj_get_returnValue(IHTMLEventObj
*iface
, VARIANT
*p
)
519 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
521 TRACE("(%p)->(%p)\n", This
, p
);
524 return VariantCopy(p
, &This
->return_value
);
527 static HRESULT WINAPI
HTMLEventObj_put_cancelBubble(IHTMLEventObj
*iface
, VARIANT_BOOL v
)
529 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
531 TRACE("(%p)->(%x)\n", This
, v
);
534 IDOMEvent_stopPropagation(&This
->event
->IDOMEvent_iface
);
538 static HRESULT WINAPI
HTMLEventObj_get_cancelBubble(IHTMLEventObj
*iface
, VARIANT_BOOL
*p
)
540 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
542 TRACE("(%p)->(%p)\n", This
, p
);
544 *p
= variant_bool(This
->event
&& This
->event
->stop_propagation
);
548 static HRESULT WINAPI
HTMLEventObj_get_fromElement(IHTMLEventObj
*iface
, IHTMLElement
**p
)
550 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
551 IDOMMouseEvent
*mouse_event
;
553 TRACE("(%p)->(%p)\n", This
, p
);
555 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
556 HRESULT hres
= IDOMMouseEvent_get_fromElement(mouse_event
, p
);
557 IDOMMouseEvent_Release(mouse_event
);
565 static HRESULT WINAPI
HTMLEventObj_get_toElement(IHTMLEventObj
*iface
, IHTMLElement
**p
)
567 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
568 IDOMMouseEvent
*mouse_event
;
570 TRACE("(%p)->(%p)\n", This
, p
);
572 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
573 HRESULT hres
= IDOMMouseEvent_get_toElement(mouse_event
, p
);
574 IDOMMouseEvent_Release(mouse_event
);
582 static HRESULT WINAPI
HTMLEventObj_put_keyCode(IHTMLEventObj
*iface
, LONG v
)
584 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
585 FIXME("(%p)->(%ld)\n", This
, v
);
589 static HRESULT WINAPI
HTMLEventObj_get_keyCode(IHTMLEventObj
*iface
, LONG
*p
)
591 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
592 IDOMKeyboardEvent
*keyboard_event
;
594 TRACE("(%p)->(%p)\n", This
, p
);
596 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMKeyboardEvent
, (void**)&keyboard_event
))) {
597 HRESULT hres
= IDOMKeyboardEvent_get_keyCode(keyboard_event
, p
);
598 IDOMKeyboardEvent_Release(keyboard_event
);
606 static HRESULT WINAPI
HTMLEventObj_get_button(IHTMLEventObj
*iface
, LONG
*p
)
608 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
609 IDOMMouseEvent
*mouse_event
;
612 TRACE("(%p)->(%p)\n", This
, p
);
614 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
615 HRESULT hres
= IDOMMouseEvent_get_button(mouse_event
, &button
);
616 IDOMMouseEvent_Release(mouse_event
);
625 static HRESULT WINAPI
HTMLEventObj_get_type(IHTMLEventObj
*iface
, BSTR
*p
)
627 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
629 TRACE("(%p)->(%p)\n", This
, p
);
636 return IDOMEvent_get_type(&This
->event
->IDOMEvent_iface
, p
);
639 static HRESULT WINAPI
HTMLEventObj_get_qualifier(IHTMLEventObj
*iface
, BSTR
*p
)
641 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
643 FIXME("(%p)->(%p)\n", This
, p
);
649 static HRESULT WINAPI
HTMLEventObj_get_reason(IHTMLEventObj
*iface
, LONG
*p
)
651 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
653 FIXME("(%p)->(%p)\n", This
, p
);
659 static HRESULT WINAPI
HTMLEventObj_get_x(IHTMLEventObj
*iface
, LONG
*p
)
661 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
664 TRACE("(%p)->(%p)\n", This
, p
);
667 nsIDOMUIEvent
*ui_event
;
668 nsresult nsres
= nsIDOMEvent_QueryInterface(This
->event
->nsevent
, &IID_nsIDOMUIEvent
, (void**)&ui_event
);
670 if(NS_SUCCEEDED(nsres
)) {
671 /* NOTE: pageX is not exactly right here. */
672 nsres
= nsIDOMUIEvent_GetPageX(ui_event
, &x
);
673 assert(nsres
== NS_OK
);
674 nsIDOMUIEvent_Release(ui_event
);
682 static HRESULT WINAPI
HTMLEventObj_get_y(IHTMLEventObj
*iface
, LONG
*p
)
684 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
687 TRACE("(%p)->(%p)\n", This
, p
);
690 nsIDOMUIEvent
*ui_event
;
691 nsresult nsres
= nsIDOMEvent_QueryInterface(This
->event
->nsevent
, &IID_nsIDOMUIEvent
, (void**)&ui_event
);
693 if(NS_SUCCEEDED(nsres
)) {
694 /* NOTE: pageY is not exactly right here. */
695 nsres
= nsIDOMUIEvent_GetPageY(ui_event
, &y
);
696 assert(nsres
== NS_OK
);
697 nsIDOMUIEvent_Release(ui_event
);
705 static HRESULT WINAPI
HTMLEventObj_get_clientX(IHTMLEventObj
*iface
, LONG
*p
)
707 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
708 IDOMMouseEvent
*mouse_event
;
710 TRACE("(%p)->(%p)\n", This
, p
);
712 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
713 HRESULT hres
= IDOMMouseEvent_get_clientX(mouse_event
, p
);
714 IDOMMouseEvent_Release(mouse_event
);
722 static HRESULT WINAPI
HTMLEventObj_get_clientY(IHTMLEventObj
*iface
, LONG
*p
)
724 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
725 IDOMMouseEvent
*mouse_event
;
727 TRACE("(%p)->(%p)\n", This
, p
);
729 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
730 HRESULT hres
= IDOMMouseEvent_get_clientY(mouse_event
, p
);
731 IDOMMouseEvent_Release(mouse_event
);
739 static HRESULT WINAPI
HTMLEventObj_get_offsetX(IHTMLEventObj
*iface
, LONG
*p
)
741 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
742 IDOMMouseEvent
*mouse_event
;
744 TRACE("(%p)->(%p)\n", This
, p
);
746 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
747 HRESULT hres
= IDOMMouseEvent_get_offsetX(mouse_event
, p
);
748 IDOMMouseEvent_Release(mouse_event
);
756 static HRESULT WINAPI
HTMLEventObj_get_offsetY(IHTMLEventObj
*iface
, LONG
*p
)
758 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
759 IDOMMouseEvent
*mouse_event
;
761 TRACE("(%p)->(%p)\n", This
, p
);
763 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
764 HRESULT hres
= IDOMMouseEvent_get_offsetY(mouse_event
, p
);
765 IDOMMouseEvent_Release(mouse_event
);
773 static HRESULT WINAPI
HTMLEventObj_get_screenX(IHTMLEventObj
*iface
, LONG
*p
)
775 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
776 IDOMMouseEvent
*mouse_event
;
778 TRACE("(%p)->(%p)\n", This
, p
);
780 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
781 HRESULT hres
= IDOMMouseEvent_get_screenX(mouse_event
, p
);
782 IDOMMouseEvent_Release(mouse_event
);
790 static HRESULT WINAPI
HTMLEventObj_get_screenY(IHTMLEventObj
*iface
, LONG
*p
)
792 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
793 IDOMMouseEvent
*mouse_event
;
795 TRACE("(%p)->(%p)\n", This
, p
);
797 if(This
->event
&& SUCCEEDED(IDOMEvent_QueryInterface(&This
->event
->IDOMEvent_iface
, &IID_IDOMMouseEvent
, (void**)&mouse_event
))) {
798 HRESULT hres
= IDOMMouseEvent_get_screenY(mouse_event
, p
);
799 IDOMMouseEvent_Release(mouse_event
);
807 static HRESULT WINAPI
HTMLEventObj_get_srcFilter(IHTMLEventObj
*iface
, IDispatch
**p
)
809 HTMLEventObj
*This
= impl_from_IHTMLEventObj(iface
);
811 FIXME("(%p)->(%p)\n", This
, p
);
817 static const IHTMLEventObjVtbl HTMLEventObjVtbl
= {
818 HTMLEventObj_QueryInterface
,
820 HTMLEventObj_Release
,
821 HTMLEventObj_GetTypeInfoCount
,
822 HTMLEventObj_GetTypeInfo
,
823 HTMLEventObj_GetIDsOfNames
,
825 HTMLEventObj_get_srcElement
,
826 HTMLEventObj_get_altKey
,
827 HTMLEventObj_get_ctrlKey
,
828 HTMLEventObj_get_shiftKey
,
829 HTMLEventObj_put_returnValue
,
830 HTMLEventObj_get_returnValue
,
831 HTMLEventObj_put_cancelBubble
,
832 HTMLEventObj_get_cancelBubble
,
833 HTMLEventObj_get_fromElement
,
834 HTMLEventObj_get_toElement
,
835 HTMLEventObj_put_keyCode
,
836 HTMLEventObj_get_keyCode
,
837 HTMLEventObj_get_button
,
838 HTMLEventObj_get_type
,
839 HTMLEventObj_get_qualifier
,
840 HTMLEventObj_get_reason
,
843 HTMLEventObj_get_clientX
,
844 HTMLEventObj_get_clientY
,
845 HTMLEventObj_get_offsetX
,
846 HTMLEventObj_get_offsetY
,
847 HTMLEventObj_get_screenX
,
848 HTMLEventObj_get_screenY
,
849 HTMLEventObj_get_srcFilter
852 static inline HTMLEventObj
*unsafe_impl_from_IHTMLEventObj(IHTMLEventObj
*iface
)
854 return iface
->lpVtbl
== &HTMLEventObjVtbl
? impl_from_IHTMLEventObj(iface
) : NULL
;
857 static inline HTMLEventObj
*HTMLEventObj_from_DispatchEx(DispatchEx
*iface
)
859 return CONTAINING_RECORD(iface
, HTMLEventObj
, dispex
);
862 static void *HTMLEventObj_query_interface(DispatchEx
*dispex
, REFIID riid
)
864 HTMLEventObj
*This
= HTMLEventObj_from_DispatchEx(dispex
);
866 if(IsEqualGUID(&IID_IHTMLEventObj
, riid
))
867 return &This
->IHTMLEventObj_iface
;
872 static void HTMLEventObj_traverse(DispatchEx
*dispex
, nsCycleCollectionTraversalCallback
*cb
)
874 HTMLEventObj
*This
= HTMLEventObj_from_DispatchEx(dispex
);
876 note_cc_edge((nsISupports
*)&This
->event
->IDOMEvent_iface
, "event", cb
);
879 static void HTMLEventObj_unlink(DispatchEx
*dispex
)
881 HTMLEventObj
*This
= HTMLEventObj_from_DispatchEx(dispex
);
883 DOMEvent
*event
= This
->event
;
885 IDOMEvent_Release(&event
->IDOMEvent_iface
);
889 static void HTMLEventObj_destructor(DispatchEx
*dispex
)
891 HTMLEventObj
*This
= HTMLEventObj_from_DispatchEx(dispex
);
895 static const dispex_static_data_vtbl_t HTMLEventObj_dispex_vtbl
= {
896 .query_interface
= HTMLEventObj_query_interface
,
897 .destructor
= HTMLEventObj_destructor
,
898 .traverse
= HTMLEventObj_traverse
,
899 .unlink
= HTMLEventObj_unlink
902 static const tid_t HTMLEventObj_iface_tids
[] = {
907 static dispex_static_data_t HTMLEventObj_dispex
= {
909 &HTMLEventObj_dispex_vtbl
,
911 HTMLEventObj_iface_tids
914 static HTMLEventObj
*alloc_event_obj(DOMEvent
*event
, compat_mode_t compat_mode
)
916 HTMLEventObj
*event_obj
;
918 event_obj
= calloc(1, sizeof(*event_obj
));
922 event_obj
->IHTMLEventObj_iface
.lpVtbl
= &HTMLEventObjVtbl
;
923 event_obj
->event
= event
;
925 IDOMEvent_AddRef(&event
->IDOMEvent_iface
);
927 init_dispatch(&event_obj
->dispex
, &HTMLEventObj_dispex
, compat_mode
);
931 HRESULT
create_event_obj(compat_mode_t compat_mode
, IHTMLEventObj
**ret
)
933 HTMLEventObj
*event_obj
;
935 event_obj
= alloc_event_obj(NULL
, compat_mode
);
937 return E_OUTOFMEMORY
;
939 *ret
= &event_obj
->IHTMLEventObj_iface
;
943 static inline DOMEvent
*impl_from_IDOMEvent(IDOMEvent
*iface
)
945 return CONTAINING_RECORD(iface
, DOMEvent
, IDOMEvent_iface
);
948 static const IDOMEventVtbl DOMEventVtbl
;
950 static inline DOMEvent
*unsafe_impl_from_IDOMEvent(IDOMEvent
*iface
)
952 return iface
&& iface
->lpVtbl
== &DOMEventVtbl
? impl_from_IDOMEvent(iface
) : NULL
;
955 static HRESULT WINAPI
DOMEvent_QueryInterface(IDOMEvent
*iface
, REFIID riid
, void **ppv
)
957 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
958 return IDispatchEx_QueryInterface(&This
->dispex
.IDispatchEx_iface
, riid
, ppv
);
961 static ULONG WINAPI
DOMEvent_AddRef(IDOMEvent
*iface
)
963 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
964 return IDispatchEx_AddRef(&This
->dispex
.IDispatchEx_iface
);
967 static ULONG WINAPI
DOMEvent_Release(IDOMEvent
*iface
)
969 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
970 return IDispatchEx_Release(&This
->dispex
.IDispatchEx_iface
);
973 static HRESULT WINAPI
DOMEvent_GetTypeInfoCount(IDOMEvent
*iface
, UINT
*pctinfo
)
975 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
976 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
979 static HRESULT WINAPI
DOMEvent_GetTypeInfo(IDOMEvent
*iface
, UINT iTInfo
,
980 LCID lcid
, ITypeInfo
**ppTInfo
)
982 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
983 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
986 static HRESULT WINAPI
DOMEvent_GetIDsOfNames(IDOMEvent
*iface
, REFIID riid
,
987 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
989 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
990 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
994 static HRESULT WINAPI
DOMEvent_Invoke(IDOMEvent
*iface
, DISPID dispIdMember
,
995 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
996 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
998 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
999 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1000 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1003 static HRESULT WINAPI
DOMEvent_get_bubbles(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
1005 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1007 TRACE("(%p)->(%p)\n", This
, p
);
1009 *p
= variant_bool(This
->bubbles
);
1013 static HRESULT WINAPI
DOMEvent_get_cancelable(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
1015 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1017 TRACE("(%p)->(%p)\n", This
, p
);
1019 *p
= variant_bool(This
->cancelable
);
1023 static HRESULT WINAPI
DOMEvent_get_currentTarget(IDOMEvent
*iface
, IEventTarget
**p
)
1025 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1027 TRACE("(%p)->(%p)\n", This
, p
);
1029 if(This
->current_target
)
1030 *p
= get_event_target_iface(This
->current_target
);
1036 static HRESULT WINAPI
DOMEvent_get_defaultPrevented(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
1038 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1040 TRACE("(%p)->(%p)\n", This
, p
);
1042 *p
= variant_bool(This
->prevent_default
);
1046 static HRESULT WINAPI
DOMEvent_get_eventPhase(IDOMEvent
*iface
, USHORT
*p
)
1048 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1050 TRACE("(%p)->(%p)\n", This
, p
);
1056 static HRESULT WINAPI
DOMEvent_get_target(IDOMEvent
*iface
, IEventTarget
**p
)
1058 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1060 TRACE("(%p)->(%p)\n", This
, p
);
1063 *p
= get_event_target_iface(This
->target
);
1069 static HRESULT WINAPI
DOMEvent_get_timeStamp(IDOMEvent
*iface
, ULONGLONG
*p
)
1071 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1073 TRACE("(%p)->(%p)\n", This
, p
);
1075 *p
= This
->time_stamp
;
1079 static HRESULT WINAPI
DOMEvent_get_type(IDOMEvent
*iface
, BSTR
*p
)
1081 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1083 TRACE("(%p)->(%p)\n", This
, p
);
1086 *p
= SysAllocString(This
->type
);
1088 return E_OUTOFMEMORY
;
1096 #define nsIDOMEvent_InitEvent(_this,type,bubbles,cancelable) \
1097 ((void (WINAPI*)(void*,nsIDOMEvent*,const nsAString*,cpp_bool,cpp_bool)) \
1098 &call_thiscall_func)((_this)->lpVtbl->InitEvent,_this,type,bubbles,cancelable)
1102 static HRESULT WINAPI
DOMEvent_initEvent(IDOMEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
, VARIANT_BOOL cancelable
)
1104 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1107 TRACE("(%p)->(%s %x %x)\n", This
, debugstr_w(type
), can_bubble
, cancelable
);
1110 TRACE("called on already dispatched event\n");
1115 This
->type
= wcsdup(type
);
1117 return E_OUTOFMEMORY
;
1118 This
->event_id
= str_to_eid(type
);
1120 This
->bubbles
= !!can_bubble
;
1121 This
->cancelable
= !!cancelable
;
1123 nsAString_InitDepend(&nsstr
, type
);
1124 nsIDOMEvent_InitEvent(This
->nsevent
, &nsstr
, This
->bubbles
, This
->cancelable
);
1125 nsAString_Finish(&nsstr
);
1130 static HRESULT WINAPI
DOMEvent_preventDefault(IDOMEvent
*iface
)
1132 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1134 TRACE("(%p)\n", This
);
1136 if(This
->current_target
&& This
->cancelable
) {
1137 This
->prevent_default
= TRUE
;
1138 nsIDOMEvent_PreventDefault(This
->nsevent
);
1143 static HRESULT WINAPI
DOMEvent_stopPropagation(IDOMEvent
*iface
)
1145 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1147 TRACE("(%p)\n", This
);
1149 This
->stop_propagation
= TRUE
;
1150 nsIDOMEvent_StopPropagation(This
->nsevent
);
1154 static HRESULT WINAPI
DOMEvent_stopImmediatePropagation(IDOMEvent
*iface
)
1156 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1158 TRACE("(%p)\n", This
);
1160 This
->stop_immediate_propagation
= This
->stop_propagation
= TRUE
;
1161 nsIDOMEvent_StopImmediatePropagation(This
->nsevent
);
1165 static HRESULT WINAPI
DOMEvent_get_isTrusted(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
1167 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1169 TRACE("(%p)->(%p)\n", This
, p
);
1171 *p
= variant_bool(This
->trusted
);
1175 static HRESULT WINAPI
DOMEvent_put_cancelBubble(IDOMEvent
*iface
, VARIANT_BOOL v
)
1177 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1178 FIXME("(%p)->(%x)\n", This
, v
);
1182 static HRESULT WINAPI
DOMEvent_get_cancelBubble(IDOMEvent
*iface
, VARIANT_BOOL
*p
)
1184 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1185 FIXME("(%p)->(%p)\n", This
, p
);
1189 static HRESULT WINAPI
DOMEvent_get_srcElement(IDOMEvent
*iface
, IHTMLElement
**p
)
1191 DOMEvent
*This
= impl_from_IDOMEvent(iface
);
1193 TRACE("(%p)->(%p)\n", This
, p
);
1196 IDispatchEx_QueryInterface(&This
->target
->dispex
.IDispatchEx_iface
, &IID_IHTMLElement
, (void**)p
);
1202 static const IDOMEventVtbl DOMEventVtbl
= {
1203 DOMEvent_QueryInterface
,
1206 DOMEvent_GetTypeInfoCount
,
1207 DOMEvent_GetTypeInfo
,
1208 DOMEvent_GetIDsOfNames
,
1210 DOMEvent_get_bubbles
,
1211 DOMEvent_get_cancelable
,
1212 DOMEvent_get_currentTarget
,
1213 DOMEvent_get_defaultPrevented
,
1214 DOMEvent_get_eventPhase
,
1215 DOMEvent_get_target
,
1216 DOMEvent_get_timeStamp
,
1219 DOMEvent_preventDefault
,
1220 DOMEvent_stopPropagation
,
1221 DOMEvent_stopImmediatePropagation
,
1222 DOMEvent_get_isTrusted
,
1223 DOMEvent_put_cancelBubble
,
1224 DOMEvent_get_cancelBubble
,
1225 DOMEvent_get_srcElement
1228 static inline DOMEvent
*DOMEvent_from_DispatchEx(DispatchEx
*iface
)
1230 return CONTAINING_RECORD(iface
, DOMEvent
, dispex
);
1233 static void *DOMEvent_query_interface(DispatchEx
*dispex
, REFIID riid
)
1235 DOMEvent
*This
= DOMEvent_from_DispatchEx(dispex
);
1237 if(IsEqualGUID(&IID_IDOMEvent
, riid
))
1238 return &This
->IDOMEvent_iface
;
1243 static void DOMEvent_traverse(DispatchEx
*dispex
, nsCycleCollectionTraversalCallback
*cb
)
1245 DOMEvent
*This
= DOMEvent_from_DispatchEx(dispex
);
1247 note_cc_edge((nsISupports
*)&This
->target
->IEventTarget_iface
, "target", cb
);
1249 note_cc_edge((nsISupports
*)This
->nsevent
, "nsevent", cb
);
1252 static void DOMEvent_unlink(DispatchEx
*dispex
)
1254 DOMEvent
*This
= DOMEvent_from_DispatchEx(dispex
);
1256 EventTarget
*target
= This
->target
;
1257 This
->target
= NULL
;
1258 IEventTarget_Release(&target
->IEventTarget_iface
);
1260 unlink_ref(&This
->nsevent
);
1263 static void DOMEvent_destructor(DispatchEx
*dispex
)
1265 DOMEvent
*This
= DOMEvent_from_DispatchEx(dispex
);
1270 static inline DOMUIEvent
*impl_from_IDOMUIEvent(IDOMUIEvent
*iface
)
1272 return CONTAINING_RECORD(iface
, DOMUIEvent
, IDOMUIEvent_iface
);
1275 static HRESULT WINAPI
DOMUIEvent_QueryInterface(IDOMUIEvent
*iface
, REFIID riid
, void **ppv
)
1277 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1278 return IDOMEvent_QueryInterface(&This
->event
.IDOMEvent_iface
, riid
, ppv
);
1281 static ULONG WINAPI
DOMUIEvent_AddRef(IDOMUIEvent
*iface
)
1283 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1284 return IDOMEvent_AddRef(&This
->event
.IDOMEvent_iface
);
1287 static ULONG WINAPI
DOMUIEvent_Release(IDOMUIEvent
*iface
)
1289 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1290 return IDOMEvent_Release(&This
->event
.IDOMEvent_iface
);
1293 static HRESULT WINAPI
DOMUIEvent_GetTypeInfoCount(IDOMUIEvent
*iface
, UINT
*pctinfo
)
1295 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1296 return IDispatchEx_GetTypeInfoCount(&This
->event
.dispex
.IDispatchEx_iface
, pctinfo
);
1299 static HRESULT WINAPI
DOMUIEvent_GetTypeInfo(IDOMUIEvent
*iface
, UINT iTInfo
,
1300 LCID lcid
, ITypeInfo
**ppTInfo
)
1302 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1303 return IDispatchEx_GetTypeInfo(&This
->event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1306 static HRESULT WINAPI
DOMUIEvent_GetIDsOfNames(IDOMUIEvent
*iface
, REFIID riid
,
1307 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1309 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1310 return IDispatchEx_GetIDsOfNames(&This
->event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1314 static HRESULT WINAPI
DOMUIEvent_Invoke(IDOMUIEvent
*iface
, DISPID dispIdMember
,
1315 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1316 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1318 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1319 return IDispatchEx_Invoke(&This
->event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1320 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1323 static HRESULT WINAPI
DOMUIEvent_get_view(IDOMUIEvent
*iface
, IHTMLWindow2
**p
)
1325 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1326 mozIDOMWindowProxy
*moz_window
;
1327 HTMLOuterWindow
*view
= NULL
;
1330 TRACE("(%p)->(%p)\n", This
, p
);
1332 nsres
= nsIDOMUIEvent_GetView(This
->nsevent
, &moz_window
);
1333 if(NS_FAILED(nsres
))
1337 view
= mozwindow_to_window(moz_window
);
1338 mozIDOMWindowProxy_Release(moz_window
);
1341 IHTMLWindow2_AddRef((*p
= &view
->base
.inner_window
->base
.IHTMLWindow2_iface
));
1347 static HRESULT WINAPI
DOMUIEvent_get_detail(IDOMUIEvent
*iface
, LONG
*p
)
1349 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1353 TRACE("(%p)->(%p)\n", This
, p
);
1355 nsres
= nsIDOMUIEvent_GetDetail(This
->nsevent
, &detail
);
1356 if(NS_FAILED(nsres
))
1363 static HRESULT WINAPI
DOMUIEvent_initUIEvent(IDOMUIEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
1364 VARIANT_BOOL cancelable
, IHTMLWindow2
*view
, LONG detail
)
1366 DOMUIEvent
*This
= impl_from_IDOMUIEvent(iface
);
1371 TRACE("(%p)->(%s %x %x %p %lx)\n", This
, debugstr_w(type
), can_bubble
, cancelable
, view
, detail
);
1373 if(This
->event
.target
) {
1374 TRACE("called on already dispatched event\n");
1379 FIXME("view argument is not supported\n");
1381 hres
= IDOMEvent_initEvent(&This
->event
.IDOMEvent_iface
, type
, can_bubble
, cancelable
);
1385 nsAString_InitDepend(&type_str
, type
);
1386 nsres
= nsIDOMUIEvent_InitUIEvent(This
->nsevent
, &type_str
, !!can_bubble
, !!cancelable
,
1387 NULL
/* FIXME */, detail
);
1388 nsAString_Finish(&type_str
);
1389 if(NS_FAILED(nsres
)) {
1390 FIXME("InitUIEvent failed: %08lx\n", nsres
);
1397 static const IDOMUIEventVtbl DOMUIEventVtbl
= {
1398 DOMUIEvent_QueryInterface
,
1401 DOMUIEvent_GetTypeInfoCount
,
1402 DOMUIEvent_GetTypeInfo
,
1403 DOMUIEvent_GetIDsOfNames
,
1405 DOMUIEvent_get_view
,
1406 DOMUIEvent_get_detail
,
1407 DOMUIEvent_initUIEvent
1410 static void *DOMUIEvent_query_interface(DispatchEx
*dispex
, REFIID riid
)
1412 DOMUIEvent
*This
= DOMUIEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
1414 if(IsEqualGUID(&IID_IDOMUIEvent
, riid
))
1415 return &This
->IDOMUIEvent_iface
;
1416 return DOMEvent_query_interface(&This
->event
.dispex
, riid
);
1419 static void DOMUIEvent_traverse(DispatchEx
*dispex
, nsCycleCollectionTraversalCallback
*cb
)
1421 DOMUIEvent
*This
= DOMUIEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
1422 DOMEvent_traverse(&This
->event
.dispex
, cb
);
1424 note_cc_edge((nsISupports
*)This
->nsevent
, "UIEvent.nsevent", cb
);
1427 static void DOMUIEvent_unlink(DispatchEx
*dispex
)
1429 DOMUIEvent
*This
= DOMUIEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
1430 DOMEvent_unlink(&This
->event
.dispex
);
1431 unlink_ref(&This
->nsevent
);
1435 DOMUIEvent ui_event
;
1436 IDOMMouseEvent IDOMMouseEvent_iface
;
1437 nsIDOMMouseEvent
*nsevent
;
1440 static inline DOMMouseEvent
*impl_from_IDOMMouseEvent(IDOMMouseEvent
*iface
)
1442 return CONTAINING_RECORD(iface
, DOMMouseEvent
, IDOMMouseEvent_iface
);
1445 static HRESULT WINAPI
DOMMouseEvent_QueryInterface(IDOMMouseEvent
*iface
, REFIID riid
, void **ppv
)
1447 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1448 return IDOMEvent_QueryInterface(&This
->ui_event
.event
.IDOMEvent_iface
, riid
, ppv
);
1451 static ULONG WINAPI
DOMMouseEvent_AddRef(IDOMMouseEvent
*iface
)
1453 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1454 return IDOMEvent_AddRef(&This
->ui_event
.event
.IDOMEvent_iface
);
1457 static ULONG WINAPI
DOMMouseEvent_Release(IDOMMouseEvent
*iface
)
1459 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1460 return IDOMEvent_Release(&This
->ui_event
.event
.IDOMEvent_iface
);
1463 static HRESULT WINAPI
DOMMouseEvent_GetTypeInfoCount(IDOMMouseEvent
*iface
, UINT
*pctinfo
)
1465 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1466 return IDispatchEx_GetTypeInfoCount(&This
->ui_event
.event
.dispex
.IDispatchEx_iface
, pctinfo
);
1469 static HRESULT WINAPI
DOMMouseEvent_GetTypeInfo(IDOMMouseEvent
*iface
, UINT iTInfo
,
1470 LCID lcid
, ITypeInfo
**ppTInfo
)
1472 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1473 return IDispatchEx_GetTypeInfo(&This
->ui_event
.event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1476 static HRESULT WINAPI
DOMMouseEvent_GetIDsOfNames(IDOMMouseEvent
*iface
, REFIID riid
,
1477 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1479 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1480 return IDispatchEx_GetIDsOfNames(&This
->ui_event
.event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1484 static HRESULT WINAPI
DOMMouseEvent_Invoke(IDOMMouseEvent
*iface
, DISPID dispIdMember
,
1485 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1486 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1488 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1489 return IDispatchEx_Invoke(&This
->ui_event
.event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
1490 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1493 static HRESULT WINAPI
DOMMouseEvent_get_screenX(IDOMMouseEvent
*iface
, LONG
*p
)
1495 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1499 TRACE("(%p)->(%p)\n", This
, p
);
1501 nsres
= nsIDOMMouseEvent_GetScreenX(This
->nsevent
, &screen_x
);
1502 if(NS_FAILED(nsres
))
1509 static HRESULT WINAPI
DOMMouseEvent_get_screenY(IDOMMouseEvent
*iface
, LONG
*p
)
1511 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1515 TRACE("(%p)->(%p)\n", This
, p
);
1517 nsres
= nsIDOMMouseEvent_GetScreenY(This
->nsevent
, &screen_y
);
1518 if(NS_FAILED(nsres
))
1525 static HRESULT WINAPI
DOMMouseEvent_get_clientX(IDOMMouseEvent
*iface
, LONG
*p
)
1527 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1531 TRACE("(%p)->(%p)\n", This
, p
);
1533 nsres
= nsIDOMMouseEvent_GetClientX(This
->nsevent
, &client_x
);
1534 if(NS_FAILED(nsres
))
1541 static HRESULT WINAPI
DOMMouseEvent_get_clientY(IDOMMouseEvent
*iface
, LONG
*p
)
1543 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1547 TRACE("(%p)->(%p)\n", This
, p
);
1549 nsres
= nsIDOMMouseEvent_GetClientY(This
->nsevent
, &client_y
);
1550 if(NS_FAILED(nsres
))
1557 static HRESULT WINAPI
DOMMouseEvent_get_ctrlKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1559 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1563 TRACE("(%p)->(%p)\n", This
, p
);
1565 nsres
= nsIDOMMouseEvent_GetCtrlKey(This
->nsevent
, &r
);
1566 if(NS_FAILED(nsres
))
1569 *p
= variant_bool(r
);
1573 static HRESULT WINAPI
DOMMouseEvent_get_shiftKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1575 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1579 TRACE("(%p)->(%p)\n", This
, p
);
1581 nsres
= nsIDOMMouseEvent_GetShiftKey(This
->nsevent
, &r
);
1582 if(NS_FAILED(nsres
))
1585 *p
= variant_bool(r
);
1589 static HRESULT WINAPI
DOMMouseEvent_get_altKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1591 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1595 TRACE("(%p)->(%p)\n", This
, p
);
1597 nsres
= nsIDOMMouseEvent_GetAltKey(This
->nsevent
, &r
);
1598 if(NS_FAILED(nsres
))
1601 *p
= variant_bool(r
);
1605 static HRESULT WINAPI
DOMMouseEvent_get_metaKey(IDOMMouseEvent
*iface
, VARIANT_BOOL
*p
)
1607 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1611 TRACE("(%p)->(%p)\n", This
, p
);
1613 nsres
= nsIDOMMouseEvent_GetMetaKey(This
->nsevent
, &r
);
1614 if(NS_FAILED(nsres
))
1617 *p
= variant_bool(r
);
1621 static HRESULT WINAPI
DOMMouseEvent_get_button(IDOMMouseEvent
*iface
, USHORT
*p
)
1623 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1627 TRACE("(%p)->(%p)\n", This
, p
);
1629 nsres
= nsIDOMMouseEvent_GetButton(This
->nsevent
, &r
);
1630 if(NS_FAILED(nsres
))
1637 static HRESULT WINAPI
DOMMouseEvent_get_relatedTarget(IDOMMouseEvent
*iface
, IEventTarget
**p
)
1639 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1640 nsIDOMEventTarget
*related_target
;
1641 nsIDOMNode
*target_node
;
1646 TRACE("(%p)->(%p)\n", This
, p
);
1648 nsres
= nsIDOMMouseEvent_GetRelatedTarget(This
->nsevent
, &related_target
);
1649 if(NS_FAILED(nsres
))
1652 if(!related_target
) {
1657 nsres
= nsIDOMEventTarget_QueryInterface(related_target
, &IID_nsIDOMNode
, (void**)&target_node
);
1658 nsIDOMEventTarget_Release(related_target
);
1659 if(NS_FAILED(nsres
)) {
1660 FIXME("Only node targets supported\n");
1664 hres
= get_node(target_node
, TRUE
, &node
);
1665 nsIDOMNode_Release(target_node
);
1669 *p
= &node
->event_target
.IEventTarget_iface
;
1673 static HRESULT WINAPI
DOMMouseEvent_initMouseEvent(IDOMMouseEvent
*iface
, BSTR type
,
1674 VARIANT_BOOL can_bubble
, VARIANT_BOOL cancelable
, IHTMLWindow2
*view
, LONG detail
,
1675 LONG screen_x
, LONG screen_y
, LONG client_x
, LONG client_y
, VARIANT_BOOL ctrl_key
,
1676 VARIANT_BOOL alt_key
, VARIANT_BOOL shift_key
, VARIANT_BOOL meta_key
, USHORT button
,
1677 IEventTarget
*related_target
)
1679 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1680 nsIDOMEventTarget
*nstarget
= NULL
;
1685 TRACE("(%p)->(%s %x %x %p %ld %ld %ld %ld %ld %x %x %x %x %u %p)\n", This
, debugstr_w(type
),
1686 can_bubble
, cancelable
, view
, detail
, screen_x
, screen_y
, client_x
, client_y
,
1687 ctrl_key
, alt_key
, shift_key
, meta_key
, button
, related_target
);
1689 if(This
->ui_event
.event
.target
) {
1690 TRACE("called on already dispatched event\n");
1695 FIXME("view argument is not supported\n");
1697 if(related_target
) {
1698 hres
= get_gecko_target(related_target
, &nstarget
);
1703 hres
= IDOMEvent_initEvent(&This
->ui_event
.event
.IDOMEvent_iface
, type
, can_bubble
, cancelable
);
1704 if(SUCCEEDED(hres
)) {
1705 nsAString_InitDepend(&type_str
, type
);
1706 nsres
= nsIDOMMouseEvent_InitMouseEvent(This
->nsevent
, &type_str
, can_bubble
, cancelable
,
1707 NULL
/* FIXME */, detail
, screen_x
, screen_y
,
1708 client_x
, client_y
, !!ctrl_key
, !!alt_key
, !!shift_key
,
1709 !!meta_key
, button
, nstarget
);
1710 nsAString_Finish(&type_str
);
1711 if(NS_FAILED(nsres
)) {
1712 FIXME("InitMouseEvent failed: %08lx\n", nsres
);
1718 nsIDOMEventTarget_Release(nstarget
);
1722 static HRESULT WINAPI
DOMMouseEvent_getModifierState(IDOMMouseEvent
*iface
, BSTR key
,
1723 VARIANT_BOOL
*activated
)
1725 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1726 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(key
), activated
);
1730 static HRESULT WINAPI
DOMMouseEvent_get_buttons(IDOMMouseEvent
*iface
, USHORT
*p
)
1732 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1736 TRACE("(%p)->(%p)\n", This
, p
);
1738 nsres
= nsIDOMMouseEvent_GetButtons(This
->nsevent
, &r
);
1739 if(NS_FAILED(nsres
))
1746 static HRESULT WINAPI
DOMMouseEvent_get_fromElement(IDOMMouseEvent
*iface
, IHTMLElement
**p
)
1748 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1749 eventid_t event_id
= This
->ui_event
.event
.event_id
;
1750 IEventTarget
*related_target
= NULL
;
1751 HRESULT hres
= S_OK
;
1753 TRACE("(%p)->(%p)\n", This
, p
);
1755 if(event_info
[event_id
].flags
& EVENT_MOUSE_FROM_RELATED
)
1756 hres
= IDOMMouseEvent_get_relatedTarget(&This
->IDOMMouseEvent_iface
, &related_target
);
1757 else if(event_info
[event_id
].flags
& EVENT_MOUSE_TO_RELATED
)
1758 hres
= IDOMEvent_get_target(&This
->ui_event
.event
.IDOMEvent_iface
, &related_target
);
1762 if(!related_target
) {
1767 IEventTarget_QueryInterface(related_target
, &IID_IHTMLElement
, (void**)p
);
1771 static HRESULT WINAPI
DOMMouseEvent_get_toElement(IDOMMouseEvent
*iface
, IHTMLElement
**p
)
1773 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1774 eventid_t event_id
= This
->ui_event
.event
.event_id
;
1775 IEventTarget
*related_target
= NULL
;
1776 HRESULT hres
= S_OK
;
1778 TRACE("(%p)->(%p)\n", This
, p
);
1780 if(event_info
[event_id
].flags
& EVENT_MOUSE_TO_RELATED
)
1781 hres
= IDOMMouseEvent_get_relatedTarget(&This
->IDOMMouseEvent_iface
, &related_target
);
1782 else if(event_info
[event_id
].flags
& EVENT_MOUSE_FROM_RELATED
)
1783 hres
= IDOMEvent_get_target(&This
->ui_event
.event
.IDOMEvent_iface
, &related_target
);
1787 if(!related_target
) {
1792 IEventTarget_QueryInterface(related_target
, &IID_IHTMLElement
, (void**)p
);
1796 static HRESULT WINAPI
DOMMouseEvent_get_x(IDOMMouseEvent
*iface
, LONG
*p
)
1798 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1799 FIXME("(%p)->(%p)\n", This
, p
);
1803 static HRESULT WINAPI
DOMMouseEvent_get_y(IDOMMouseEvent
*iface
, LONG
*p
)
1805 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1806 FIXME("(%p)->(%p)\n", This
, p
);
1810 static HRESULT WINAPI
DOMMouseEvent_get_offsetX(IDOMMouseEvent
*iface
, LONG
*p
)
1812 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1814 FIXME("(%p)->(%p) returning 0\n", This
, p
);
1820 static HRESULT WINAPI
DOMMouseEvent_get_offsetY(IDOMMouseEvent
*iface
, LONG
*p
)
1822 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1824 FIXME("(%p)->(%p) returning 0\n", This
, p
);
1830 static HRESULT WINAPI
DOMMouseEvent_get_pageX(IDOMMouseEvent
*iface
, LONG
*p
)
1832 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1836 TRACE("(%p)->(%p)\n", This
, p
);
1838 nsres
= nsIDOMMouseEvent_GetPageX(This
->nsevent
, &r
);
1839 if(NS_FAILED(nsres
))
1846 static HRESULT WINAPI
DOMMouseEvent_get_pageY(IDOMMouseEvent
*iface
, LONG
*p
)
1848 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1852 TRACE("(%p)->(%p)\n", This
, p
);
1854 nsres
= nsIDOMMouseEvent_GetPageY(This
->nsevent
, &r
);
1855 if(NS_FAILED(nsres
))
1862 static HRESULT WINAPI
DOMMouseEvent_get_layerX(IDOMMouseEvent
*iface
, LONG
*p
)
1864 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1868 TRACE("(%p)->(%p)\n", This
, p
);
1870 nsres
= nsIDOMMouseEvent_GetLayerX(This
->nsevent
, &r
);
1871 if(NS_FAILED(nsres
))
1878 static HRESULT WINAPI
DOMMouseEvent_get_layerY(IDOMMouseEvent
*iface
, LONG
*p
)
1880 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1884 TRACE("(%p)->(%p)\n", This
, p
);
1886 nsres
= nsIDOMMouseEvent_GetLayerY(This
->nsevent
, &r
);
1887 if(NS_FAILED(nsres
))
1894 static HRESULT WINAPI
DOMMouseEvent_get_which(IDOMMouseEvent
*iface
, USHORT
*p
)
1896 DOMMouseEvent
*This
= impl_from_IDOMMouseEvent(iface
);
1900 TRACE("(%p)->(%p)\n", This
, p
);
1902 nsres
= nsIDOMMouseEvent_GetWhich(This
->nsevent
, &r
);
1903 if(NS_FAILED(nsres
))
1910 static const IDOMMouseEventVtbl DOMMouseEventVtbl
= {
1911 DOMMouseEvent_QueryInterface
,
1912 DOMMouseEvent_AddRef
,
1913 DOMMouseEvent_Release
,
1914 DOMMouseEvent_GetTypeInfoCount
,
1915 DOMMouseEvent_GetTypeInfo
,
1916 DOMMouseEvent_GetIDsOfNames
,
1917 DOMMouseEvent_Invoke
,
1918 DOMMouseEvent_get_screenX
,
1919 DOMMouseEvent_get_screenY
,
1920 DOMMouseEvent_get_clientX
,
1921 DOMMouseEvent_get_clientY
,
1922 DOMMouseEvent_get_ctrlKey
,
1923 DOMMouseEvent_get_shiftKey
,
1924 DOMMouseEvent_get_altKey
,
1925 DOMMouseEvent_get_metaKey
,
1926 DOMMouseEvent_get_button
,
1927 DOMMouseEvent_get_relatedTarget
,
1928 DOMMouseEvent_initMouseEvent
,
1929 DOMMouseEvent_getModifierState
,
1930 DOMMouseEvent_get_buttons
,
1931 DOMMouseEvent_get_fromElement
,
1932 DOMMouseEvent_get_toElement
,
1933 DOMMouseEvent_get_x
,
1934 DOMMouseEvent_get_y
,
1935 DOMMouseEvent_get_offsetX
,
1936 DOMMouseEvent_get_offsetY
,
1937 DOMMouseEvent_get_pageX
,
1938 DOMMouseEvent_get_pageY
,
1939 DOMMouseEvent_get_layerX
,
1940 DOMMouseEvent_get_layerY
,
1941 DOMMouseEvent_get_which
1944 static DOMMouseEvent
*DOMMouseEvent_from_DOMEvent(DOMEvent
*event
)
1946 return CONTAINING_RECORD(event
, DOMMouseEvent
, ui_event
.event
);
1949 static void *DOMMouseEvent_query_interface(DispatchEx
*dispex
, REFIID riid
)
1951 DOMMouseEvent
*This
= DOMMouseEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
1953 if(IsEqualGUID(&IID_IDOMMouseEvent
, riid
))
1954 return &This
->IDOMMouseEvent_iface
;
1955 if(IsEqualGUID(&IID_IDOMUIEvent
, riid
))
1956 return &This
->ui_event
.IDOMUIEvent_iface
;
1957 return DOMEvent_query_interface(&This
->ui_event
.event
.dispex
, riid
);
1960 static void DOMMouseEvent_traverse(DispatchEx
*dispex
, nsCycleCollectionTraversalCallback
*cb
)
1962 DOMMouseEvent
*This
= DOMMouseEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
1963 DOMUIEvent_traverse(&This
->ui_event
.event
.dispex
, cb
);
1965 note_cc_edge((nsISupports
*)This
->nsevent
, "MouseEvent.nsevent", cb
);
1968 static void DOMMouseEvent_unlink(DispatchEx
*dispex
)
1970 DOMMouseEvent
*This
= DOMMouseEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
1971 DOMUIEvent_unlink(&This
->ui_event
.event
.dispex
);
1972 unlink_ref(&This
->nsevent
);
1976 DOMUIEvent ui_event
;
1977 IDOMKeyboardEvent IDOMKeyboardEvent_iface
;
1978 nsIDOMKeyEvent
*nsevent
;
1981 static inline DOMKeyboardEvent
*impl_from_IDOMKeyboardEvent(IDOMKeyboardEvent
*iface
)
1983 return CONTAINING_RECORD(iface
, DOMKeyboardEvent
, IDOMKeyboardEvent_iface
);
1986 static HRESULT WINAPI
DOMKeyboardEvent_QueryInterface(IDOMKeyboardEvent
*iface
, REFIID riid
, void **ppv
)
1988 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1989 return IDOMEvent_QueryInterface(&This
->ui_event
.event
.IDOMEvent_iface
, riid
, ppv
);
1992 static ULONG WINAPI
DOMKeyboardEvent_AddRef(IDOMKeyboardEvent
*iface
)
1994 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
1995 return IDOMEvent_AddRef(&This
->ui_event
.event
.IDOMEvent_iface
);
1998 static ULONG WINAPI
DOMKeyboardEvent_Release(IDOMKeyboardEvent
*iface
)
2000 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2001 return IDOMEvent_Release(&This
->ui_event
.event
.IDOMEvent_iface
);
2004 static HRESULT WINAPI
DOMKeyboardEvent_GetTypeInfoCount(IDOMKeyboardEvent
*iface
, UINT
*pctinfo
)
2006 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2007 return IDispatchEx_GetTypeInfoCount(&This
->ui_event
.event
.dispex
.IDispatchEx_iface
, pctinfo
);
2010 static HRESULT WINAPI
DOMKeyboardEvent_GetTypeInfo(IDOMKeyboardEvent
*iface
, UINT iTInfo
,
2011 LCID lcid
, ITypeInfo
**ppTInfo
)
2013 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2014 return IDispatchEx_GetTypeInfo(&This
->ui_event
.event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
2017 static HRESULT WINAPI
DOMKeyboardEvent_GetIDsOfNames(IDOMKeyboardEvent
*iface
, REFIID riid
,
2018 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2020 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2021 return IDispatchEx_GetIDsOfNames(&This
->ui_event
.event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
2025 static HRESULT WINAPI
DOMKeyboardEvent_Invoke(IDOMKeyboardEvent
*iface
, DISPID dispIdMember
,
2026 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2027 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2029 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2030 return IDispatchEx_Invoke(&This
->ui_event
.event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
2031 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2034 static HRESULT WINAPI
DOMKeyboardEvent_get_key(IDOMKeyboardEvent
*iface
, BSTR
*p
)
2036 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2040 TRACE("(%p)->(%p)\n", This
, p
);
2043 nsAString_Init(&key_str
, NULL
);
2044 nsres
= nsIDOMKeyEvent_GetKey(This
->nsevent
, &key_str
);
2045 return return_nsstr(nsres
, &key_str
, p
);
2048 static HRESULT WINAPI
DOMKeyboardEvent_get_location(IDOMKeyboardEvent
*iface
, ULONG
*p
)
2050 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2054 TRACE("(%p)->(%p)\n", This
, p
);
2056 nsres
= nsIDOMKeyEvent_GetLocation(This
->nsevent
, &r
);
2057 if(NS_FAILED(nsres
))
2064 static HRESULT WINAPI
DOMKeyboardEvent_get_ctrlKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
2066 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2070 TRACE("(%p)->(%p)\n", This
, p
);
2072 nsres
= nsIDOMKeyEvent_GetCtrlKey(This
->nsevent
, &r
);
2073 if(NS_FAILED(nsres
))
2076 *p
= variant_bool(r
);
2080 static HRESULT WINAPI
DOMKeyboardEvent_get_shiftKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
2082 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2086 TRACE("(%p)->(%p)\n", This
, p
);
2088 nsres
= nsIDOMKeyEvent_GetShiftKey(This
->nsevent
, &r
);
2089 if(NS_FAILED(nsres
))
2092 *p
= variant_bool(r
);
2096 static HRESULT WINAPI
DOMKeyboardEvent_get_altKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
2098 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2102 TRACE("(%p)->(%p)\n", This
, p
);
2104 nsres
= nsIDOMKeyEvent_GetAltKey(This
->nsevent
, &r
);
2105 if(NS_FAILED(nsres
))
2108 *p
= variant_bool(r
);
2112 static HRESULT WINAPI
DOMKeyboardEvent_get_metaKey(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
2114 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2118 TRACE("(%p)->(%p)\n", This
, p
);
2120 nsres
= nsIDOMKeyEvent_GetMetaKey(This
->nsevent
, &r
);
2121 if(NS_FAILED(nsres
))
2124 *p
= variant_bool(r
);
2128 static HRESULT WINAPI
DOMKeyboardEvent_get_repeat(IDOMKeyboardEvent
*iface
, VARIANT_BOOL
*p
)
2130 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2134 TRACE("(%p)->(%p)\n", This
, p
);
2136 nsres
= nsIDOMKeyEvent_GetRepeat(This
->nsevent
, &r
);
2137 if(NS_FAILED(nsres
))
2140 *p
= variant_bool(r
);
2144 static HRESULT WINAPI
DOMKeyboardEvent_getModifierState(IDOMKeyboardEvent
*iface
, BSTR key
,
2145 VARIANT_BOOL
*state
)
2147 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2148 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(key
), state
);
2152 static HRESULT WINAPI
DOMKeyboardEvent_initKeyboardEvent(IDOMKeyboardEvent
*iface
, BSTR type
,
2153 VARIANT_BOOL can_bubble
, VARIANT_BOOL cancelable
, IHTMLWindow2
*view
, BSTR key
,
2154 ULONG location
, BSTR modifiers_list
, VARIANT_BOOL repeat
, BSTR locale
)
2156 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2157 FIXME("(%p)->(%s %x %x %p %s %lu %s %x %s)\n", This
, debugstr_w(type
), can_bubble
,
2158 cancelable
, view
, debugstr_w(key
), location
, debugstr_w(modifiers_list
),
2159 repeat
, debugstr_w(locale
));
2163 static HRESULT WINAPI
DOMKeyboardEvent_get_keyCode(IDOMKeyboardEvent
*iface
, LONG
*p
)
2165 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2169 TRACE("(%p)->(%p)\n", This
, p
);
2171 nsres
= nsIDOMKeyEvent_GetKeyCode(This
->nsevent
, &r
);
2172 if(NS_FAILED(nsres
))
2179 static HRESULT WINAPI
DOMKeyboardEvent_get_charCode(IDOMKeyboardEvent
*iface
, LONG
*p
)
2181 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2185 TRACE("(%p)->(%p)\n", This
, p
);
2187 nsres
= nsIDOMKeyEvent_GetKeyCode(This
->nsevent
, &r
);
2188 if(NS_FAILED(nsres
))
2195 static HRESULT WINAPI
DOMKeyboardEvent_get_which(IDOMKeyboardEvent
*iface
, LONG
*p
)
2197 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2201 TRACE("(%p)->(%p)\n", This
, p
);
2203 nsres
= nsIDOMKeyEvent_GetWhich(This
->nsevent
, &r
);
2204 if(NS_FAILED(nsres
))
2211 static HRESULT WINAPI
DOMKeyboardEvent_get_char(IDOMKeyboardEvent
*iface
, VARIANT
*p
)
2213 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2214 FIXME("(%p)->(%p)\n", This
, p
);
2218 static HRESULT WINAPI
DOMKeyboardEvent_get_locale(IDOMKeyboardEvent
*iface
, BSTR
*p
)
2220 DOMKeyboardEvent
*This
= impl_from_IDOMKeyboardEvent(iface
);
2222 FIXME("(%p)->(%p) semi-stub\n", This
, p
);
2224 *p
= SysAllocString(L
"");
2225 return *p
? S_OK
: E_OUTOFMEMORY
;
2228 static const IDOMKeyboardEventVtbl DOMKeyboardEventVtbl
= {
2229 DOMKeyboardEvent_QueryInterface
,
2230 DOMKeyboardEvent_AddRef
,
2231 DOMKeyboardEvent_Release
,
2232 DOMKeyboardEvent_GetTypeInfoCount
,
2233 DOMKeyboardEvent_GetTypeInfo
,
2234 DOMKeyboardEvent_GetIDsOfNames
,
2235 DOMKeyboardEvent_Invoke
,
2236 DOMKeyboardEvent_get_key
,
2237 DOMKeyboardEvent_get_location
,
2238 DOMKeyboardEvent_get_ctrlKey
,
2239 DOMKeyboardEvent_get_shiftKey
,
2240 DOMKeyboardEvent_get_altKey
,
2241 DOMKeyboardEvent_get_metaKey
,
2242 DOMKeyboardEvent_get_repeat
,
2243 DOMKeyboardEvent_getModifierState
,
2244 DOMKeyboardEvent_initKeyboardEvent
,
2245 DOMKeyboardEvent_get_keyCode
,
2246 DOMKeyboardEvent_get_charCode
,
2247 DOMKeyboardEvent_get_which
,
2248 DOMKeyboardEvent_get_char
,
2249 DOMKeyboardEvent_get_locale
2252 static DOMKeyboardEvent
*DOMKeyboardEvent_from_DOMEvent(DOMEvent
*event
)
2254 return CONTAINING_RECORD(event
, DOMKeyboardEvent
, ui_event
.event
);
2257 static void *DOMKeyboardEvent_query_interface(DispatchEx
*dispex
, REFIID riid
)
2259 DOMKeyboardEvent
*This
= DOMKeyboardEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
2261 if(IsEqualGUID(&IID_IDOMKeyboardEvent
, riid
))
2262 return &This
->IDOMKeyboardEvent_iface
;
2263 if(IsEqualGUID(&IID_IDOMUIEvent
, riid
))
2264 return &This
->ui_event
.IDOMUIEvent_iface
;
2265 return DOMEvent_query_interface(&This
->ui_event
.event
.dispex
, riid
);
2268 static void DOMKeyboardEvent_traverse(DispatchEx
*dispex
, nsCycleCollectionTraversalCallback
*cb
)
2270 DOMKeyboardEvent
*This
= DOMKeyboardEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
2271 DOMUIEvent_traverse(&This
->ui_event
.event
.dispex
, cb
);
2273 note_cc_edge((nsISupports
*)This
->nsevent
, "KeyboardEvent.nsevent", cb
);
2276 static void DOMKeyboardEvent_unlink(DispatchEx
*dispex
)
2278 DOMKeyboardEvent
*This
= DOMKeyboardEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
2279 DOMUIEvent_unlink(&This
->ui_event
.event
.dispex
);
2280 unlink_ref(&This
->nsevent
);
2285 IWinePageTransitionEvent IWinePageTransitionEvent_iface
;
2286 } DOMPageTransitionEvent
;
2288 static inline DOMPageTransitionEvent
*impl_from_IWinePageTransitionEvent(IWinePageTransitionEvent
*iface
)
2290 return CONTAINING_RECORD(iface
, DOMPageTransitionEvent
, IWinePageTransitionEvent_iface
);
2293 static HRESULT WINAPI
DOMPageTransitionEvent_QueryInterface(IWinePageTransitionEvent
*iface
, REFIID riid
, void **ppv
)
2295 DOMPageTransitionEvent
*This
= impl_from_IWinePageTransitionEvent(iface
);
2296 return IDOMEvent_QueryInterface(&This
->event
.IDOMEvent_iface
, riid
, ppv
);
2299 static ULONG WINAPI
DOMPageTransitionEvent_AddRef(IWinePageTransitionEvent
*iface
)
2301 DOMPageTransitionEvent
*This
= impl_from_IWinePageTransitionEvent(iface
);
2302 return IDOMEvent_AddRef(&This
->event
.IDOMEvent_iface
);
2305 static ULONG WINAPI
DOMPageTransitionEvent_Release(IWinePageTransitionEvent
*iface
)
2307 DOMPageTransitionEvent
*This
= impl_from_IWinePageTransitionEvent(iface
);
2308 return IDOMEvent_Release(&This
->event
.IDOMEvent_iface
);
2311 static HRESULT WINAPI
DOMPageTransitionEvent_GetTypeInfoCount(IWinePageTransitionEvent
*iface
, UINT
*pctinfo
)
2313 DOMPageTransitionEvent
*This
= impl_from_IWinePageTransitionEvent(iface
);
2314 return IDispatchEx_GetTypeInfoCount(&This
->event
.dispex
.IDispatchEx_iface
, pctinfo
);
2317 static HRESULT WINAPI
DOMPageTransitionEvent_GetTypeInfo(IWinePageTransitionEvent
*iface
, UINT iTInfo
,
2318 LCID lcid
, ITypeInfo
**ppTInfo
)
2320 DOMPageTransitionEvent
*This
= impl_from_IWinePageTransitionEvent(iface
);
2321 return IDispatchEx_GetTypeInfo(&This
->event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
2324 static HRESULT WINAPI
DOMPageTransitionEvent_GetIDsOfNames(IWinePageTransitionEvent
*iface
, REFIID riid
,
2325 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2327 DOMPageTransitionEvent
*This
= impl_from_IWinePageTransitionEvent(iface
);
2328 return IDispatchEx_GetIDsOfNames(&This
->event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
2332 static HRESULT WINAPI
DOMPageTransitionEvent_Invoke(IWinePageTransitionEvent
*iface
, DISPID dispIdMember
,
2333 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2334 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2336 DOMPageTransitionEvent
*This
= impl_from_IWinePageTransitionEvent(iface
);
2337 return IDispatchEx_Invoke(&This
->event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
2338 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2341 static HRESULT WINAPI
DOMPageTransitionEvent_get_persisted(IWinePageTransitionEvent
*iface
, VARIANT_BOOL
*p
)
2343 DOMPageTransitionEvent
*This
= impl_from_IWinePageTransitionEvent(iface
);
2345 FIXME("(%p)->(%p): always returning FALSE\n", This
, p
);
2351 static const IWinePageTransitionEventVtbl DOMPageTransitionEventVtbl
= {
2352 DOMPageTransitionEvent_QueryInterface
,
2353 DOMPageTransitionEvent_AddRef
,
2354 DOMPageTransitionEvent_Release
,
2355 DOMPageTransitionEvent_GetTypeInfoCount
,
2356 DOMPageTransitionEvent_GetTypeInfo
,
2357 DOMPageTransitionEvent_GetIDsOfNames
,
2358 DOMPageTransitionEvent_Invoke
,
2359 DOMPageTransitionEvent_get_persisted
2362 static DOMPageTransitionEvent
*DOMPageTransitionEvent_from_DOMEvent(DOMEvent
*event
)
2364 return CONTAINING_RECORD(event
, DOMPageTransitionEvent
, event
);
2367 static void *DOMPageTransitionEvent_query_interface(DispatchEx
*dispex
, REFIID riid
)
2369 DOMPageTransitionEvent
*page_transition_event
= DOMPageTransitionEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
2371 if(IsEqualGUID(&IID_IWinePageTransitionEvent
, riid
))
2372 return &page_transition_event
->IWinePageTransitionEvent_iface
;
2373 return DOMEvent_query_interface(&page_transition_event
->event
.dispex
, riid
);
2378 IDOMCustomEvent IDOMCustomEvent_iface
;
2382 static inline DOMCustomEvent
*impl_from_IDOMCustomEvent(IDOMCustomEvent
*iface
)
2384 return CONTAINING_RECORD(iface
, DOMCustomEvent
, IDOMCustomEvent_iface
);
2387 static HRESULT WINAPI
DOMCustomEvent_QueryInterface(IDOMCustomEvent
*iface
, REFIID riid
, void **ppv
)
2389 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2390 return IDOMEvent_QueryInterface(&This
->event
.IDOMEvent_iface
, riid
, ppv
);
2393 static ULONG WINAPI
DOMCustomEvent_AddRef(IDOMCustomEvent
*iface
)
2395 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2396 return IDOMEvent_AddRef(&This
->event
.IDOMEvent_iface
);
2399 static ULONG WINAPI
DOMCustomEvent_Release(IDOMCustomEvent
*iface
)
2401 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2402 return IDOMEvent_Release(&This
->event
.IDOMEvent_iface
);
2405 static HRESULT WINAPI
DOMCustomEvent_GetTypeInfoCount(IDOMCustomEvent
*iface
, UINT
*pctinfo
)
2407 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2408 return IDispatchEx_GetTypeInfoCount(&This
->event
.dispex
.IDispatchEx_iface
, pctinfo
);
2411 static HRESULT WINAPI
DOMCustomEvent_GetTypeInfo(IDOMCustomEvent
*iface
, UINT iTInfo
,
2412 LCID lcid
, ITypeInfo
**ppTInfo
)
2414 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2415 return IDispatchEx_GetTypeInfo(&This
->event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
2418 static HRESULT WINAPI
DOMCustomEvent_GetIDsOfNames(IDOMCustomEvent
*iface
, REFIID riid
,
2419 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2421 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2422 return IDispatchEx_GetIDsOfNames(&This
->event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
2426 static HRESULT WINAPI
DOMCustomEvent_Invoke(IDOMCustomEvent
*iface
, DISPID dispIdMember
,
2427 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2428 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2430 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2431 return IDispatchEx_Invoke(&This
->event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
2432 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2435 static HRESULT WINAPI
DOMCustomEvent_get_detail(IDOMCustomEvent
*iface
, VARIANT
*p
)
2437 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2439 TRACE("(%p)->(%p)\n", This
, p
);
2442 return VariantCopy(p
, &This
->detail
);
2445 static HRESULT WINAPI
DOMCustomEvent_initCustomEvent(IDOMCustomEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
2446 VARIANT_BOOL cancelable
, VARIANT
*detail
)
2448 DOMCustomEvent
*This
= impl_from_IDOMCustomEvent(iface
);
2451 TRACE("(%p)->(%s %x %x %s)\n", This
, debugstr_w(type
), can_bubble
, cancelable
, debugstr_variant(detail
));
2453 hres
= IDOMEvent_initEvent(&This
->event
.IDOMEvent_iface
, type
, can_bubble
, cancelable
);
2457 return VariantCopy(&This
->detail
, detail
);
2460 static const IDOMCustomEventVtbl DOMCustomEventVtbl
= {
2461 DOMCustomEvent_QueryInterface
,
2462 DOMCustomEvent_AddRef
,
2463 DOMCustomEvent_Release
,
2464 DOMCustomEvent_GetTypeInfoCount
,
2465 DOMCustomEvent_GetTypeInfo
,
2466 DOMCustomEvent_GetIDsOfNames
,
2467 DOMCustomEvent_Invoke
,
2468 DOMCustomEvent_get_detail
,
2469 DOMCustomEvent_initCustomEvent
2472 static DOMCustomEvent
*DOMCustomEvent_from_DOMEvent(DOMEvent
*event
)
2474 return CONTAINING_RECORD(event
, DOMCustomEvent
, event
);
2477 static void *DOMCustomEvent_query_interface(DispatchEx
*dispex
, REFIID riid
)
2479 DOMCustomEvent
*custom_event
= DOMCustomEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
2481 if(IsEqualGUID(&IID_IDOMCustomEvent
, riid
))
2482 return &custom_event
->IDOMCustomEvent_iface
;
2483 return DOMEvent_query_interface(&custom_event
->event
.dispex
, riid
);
2486 static void DOMCustomEvent_traverse(DispatchEx
*dispex
, nsCycleCollectionTraversalCallback
*cb
)
2488 DOMCustomEvent
*custom_event
= DOMCustomEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
2489 DOMEvent_traverse(&custom_event
->event
.dispex
, cb
);
2490 traverse_variant(&custom_event
->detail
, "detail", cb
);
2493 static void DOMCustomEvent_unlink(DispatchEx
*dispex
)
2495 DOMCustomEvent
*custom_event
= DOMCustomEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
2496 DOMEvent_unlink(&custom_event
->event
.dispex
);
2497 unlink_variant(&custom_event
->detail
);
2500 static void DOMCustomEvent_destructor(DispatchEx
*dispex
)
2502 DOMCustomEvent
*custom_event
= DOMCustomEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
2503 VariantClear(&custom_event
->detail
);
2504 DOMEvent_destructor(dispex
);
2509 IDOMMessageEvent IDOMMessageEvent_iface
;
2513 static inline DOMMessageEvent
*impl_from_IDOMMessageEvent(IDOMMessageEvent
*iface
)
2515 return CONTAINING_RECORD(iface
, DOMMessageEvent
, IDOMMessageEvent_iface
);
2518 static HRESULT WINAPI
DOMMessageEvent_QueryInterface(IDOMMessageEvent
*iface
, REFIID riid
, void **ppv
)
2520 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2521 return IDOMEvent_QueryInterface(&This
->event
.IDOMEvent_iface
, riid
, ppv
);
2524 static ULONG WINAPI
DOMMessageEvent_AddRef(IDOMMessageEvent
*iface
)
2526 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2527 return IDOMEvent_AddRef(&This
->event
.IDOMEvent_iface
);
2530 static ULONG WINAPI
DOMMessageEvent_Release(IDOMMessageEvent
*iface
)
2532 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2533 return IDOMEvent_Release(&This
->event
.IDOMEvent_iface
);
2536 static HRESULT WINAPI
DOMMessageEvent_GetTypeInfoCount(IDOMMessageEvent
*iface
, UINT
*pctinfo
)
2538 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2539 return IDispatchEx_GetTypeInfoCount(&This
->event
.dispex
.IDispatchEx_iface
, pctinfo
);
2542 static HRESULT WINAPI
DOMMessageEvent_GetTypeInfo(IDOMMessageEvent
*iface
, UINT iTInfo
,
2543 LCID lcid
, ITypeInfo
**ppTInfo
)
2545 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2546 return IDispatchEx_GetTypeInfo(&This
->event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
2549 static HRESULT WINAPI
DOMMessageEvent_GetIDsOfNames(IDOMMessageEvent
*iface
, REFIID riid
,
2550 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2552 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2553 return IDispatchEx_GetIDsOfNames(&This
->event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
2557 static HRESULT WINAPI
DOMMessageEvent_Invoke(IDOMMessageEvent
*iface
, DISPID dispIdMember
,
2558 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2559 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2561 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2562 return IDispatchEx_Invoke(&This
->event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
2563 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2566 static HRESULT WINAPI
DOMMessageEvent_get_data(IDOMMessageEvent
*iface
, BSTR
*p
)
2568 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2570 TRACE("(%p)->(%p)\n", This
, p
);
2572 if(V_VT(&This
->data
) != VT_BSTR
) {
2573 FIXME("non-string data\n");
2577 return (*p
= SysAllocString(V_BSTR(&This
->data
))) ? S_OK
: E_OUTOFMEMORY
;
2580 static HRESULT
DOMMessageEvent_get_data_hook(DispatchEx
*dispex
, WORD flags
, DISPPARAMS
*dp
, VARIANT
*res
,
2581 EXCEPINFO
*ei
, IServiceProvider
*caller
)
2583 DOMMessageEvent
*This
= CONTAINING_RECORD(dispex
, DOMMessageEvent
, event
.dispex
);
2585 if(!(flags
& DISPATCH_PROPERTYGET
) || !res
)
2588 TRACE("(%p)->(%p)\n", This
, res
);
2590 V_VT(res
) = VT_EMPTY
;
2591 return VariantCopy(res
, &This
->data
);
2594 static HRESULT WINAPI
DOMMessageEvent_get_origin(IDOMMessageEvent
*iface
, BSTR
*p
)
2596 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2597 FIXME("(%p)->(%p)\n", This
, p
);
2601 static HRESULT WINAPI
DOMMessageEvent_get_source(IDOMMessageEvent
*iface
, IHTMLWindow2
**p
)
2603 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2604 FIXME("(%p)->(%p)\n", This
, p
);
2608 static HRESULT WINAPI
DOMMessageEvent_initMessageEvent(IDOMMessageEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
2609 VARIANT_BOOL cancelable
, BSTR data
, BSTR origin
,
2610 BSTR last_event_id
, IHTMLWindow2
*source
)
2612 DOMMessageEvent
*This
= impl_from_IDOMMessageEvent(iface
);
2613 FIXME("(%p)->(%s %x %x %s %s %s %p)\n", This
, debugstr_w(type
), can_bubble
, cancelable
,
2614 debugstr_w(data
), debugstr_w(origin
), debugstr_w(last_event_id
), source
);
2618 static const IDOMMessageEventVtbl DOMMessageEventVtbl
= {
2619 DOMMessageEvent_QueryInterface
,
2620 DOMMessageEvent_AddRef
,
2621 DOMMessageEvent_Release
,
2622 DOMMessageEvent_GetTypeInfoCount
,
2623 DOMMessageEvent_GetTypeInfo
,
2624 DOMMessageEvent_GetIDsOfNames
,
2625 DOMMessageEvent_Invoke
,
2626 DOMMessageEvent_get_data
,
2627 DOMMessageEvent_get_origin
,
2628 DOMMessageEvent_get_source
,
2629 DOMMessageEvent_initMessageEvent
2632 static DOMMessageEvent
*DOMMessageEvent_from_DOMEvent(DOMEvent
*event
)
2634 return CONTAINING_RECORD(event
, DOMMessageEvent
, event
);
2637 static void *DOMMessageEvent_query_interface(DispatchEx
*dispex
, REFIID riid
)
2639 DOMMessageEvent
*message_event
= DOMMessageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
2641 if(IsEqualGUID(&IID_IDOMMessageEvent
, riid
))
2642 return &message_event
->IDOMMessageEvent_iface
;
2643 return DOMEvent_query_interface(&message_event
->event
.dispex
, riid
);
2646 static void DOMMessageEvent_traverse(DispatchEx
*dispex
, nsCycleCollectionTraversalCallback
*cb
)
2648 DOMMessageEvent
*message_event
= DOMMessageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
2649 DOMEvent_traverse(&message_event
->event
.dispex
, cb
);
2650 traverse_variant(&message_event
->data
, "data", cb
);
2653 static void DOMMessageEvent_unlink(DispatchEx
*dispex
)
2655 DOMMessageEvent
*message_event
= DOMMessageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
2656 DOMEvent_unlink(&message_event
->event
.dispex
);
2657 unlink_variant(&message_event
->data
);
2660 static void DOMMessageEvent_destructor(DispatchEx
*dispex
)
2662 DOMMessageEvent
*message_event
= DOMMessageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
2663 VariantClear(&message_event
->data
);
2664 DOMEvent_destructor(dispex
);
2667 static void DOMMessageEvent_init_dispex_info(dispex_data_t
*info
, compat_mode_t compat_mode
)
2669 static const dispex_hook_t hooks
[] = {
2670 {DISPID_IDOMMESSAGEEVENT_DATA
, DOMMessageEvent_get_data_hook
},
2673 dispex_info_add_interface(info
, IDOMMessageEvent_tid
, compat_mode
>= COMPAT_MODE_IE10
? hooks
: NULL
);
2678 IDOMProgressEvent IDOMProgressEvent_iface
;
2679 nsIDOMProgressEvent
*nsevent
;
2683 static inline DOMProgressEvent
*impl_from_IDOMProgressEvent(IDOMProgressEvent
*iface
)
2685 return CONTAINING_RECORD(iface
, DOMProgressEvent
, IDOMProgressEvent_iface
);
2688 static HRESULT WINAPI
DOMProgressEvent_QueryInterface(IDOMProgressEvent
*iface
, REFIID riid
, void **ppv
)
2690 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2691 return IDOMEvent_QueryInterface(&This
->event
.IDOMEvent_iface
, riid
, ppv
);
2694 static ULONG WINAPI
DOMProgressEvent_AddRef(IDOMProgressEvent
*iface
)
2696 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2697 return IDOMEvent_AddRef(&This
->event
.IDOMEvent_iface
);
2700 static ULONG WINAPI
DOMProgressEvent_Release(IDOMProgressEvent
*iface
)
2702 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2703 return IDOMEvent_Release(&This
->event
.IDOMEvent_iface
);
2706 static HRESULT WINAPI
DOMProgressEvent_GetTypeInfoCount(IDOMProgressEvent
*iface
, UINT
*pctinfo
)
2708 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2709 return IDispatchEx_GetTypeInfoCount(&This
->event
.dispex
.IDispatchEx_iface
, pctinfo
);
2712 static HRESULT WINAPI
DOMProgressEvent_GetTypeInfo(IDOMProgressEvent
*iface
, UINT iTInfo
,
2713 LCID lcid
, ITypeInfo
**ppTInfo
)
2715 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2716 return IDispatchEx_GetTypeInfo(&This
->event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
2719 static HRESULT WINAPI
DOMProgressEvent_GetIDsOfNames(IDOMProgressEvent
*iface
, REFIID riid
,
2720 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2722 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2723 return IDispatchEx_GetIDsOfNames(&This
->event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
2727 static HRESULT WINAPI
DOMProgressEvent_Invoke(IDOMProgressEvent
*iface
, DISPID dispIdMember
,
2728 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2729 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2731 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2732 return IDispatchEx_Invoke(&This
->event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
2733 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2736 static HRESULT WINAPI
DOMProgressEvent_get_lengthComputable(IDOMProgressEvent
*iface
, VARIANT_BOOL
*p
)
2738 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2742 TRACE("(%p)->(%p)\n", This
, p
);
2744 nsres
= nsIDOMProgressEvent_GetLengthComputable(This
->nsevent
, &b
);
2745 if(NS_FAILED(nsres
))
2746 return map_nsresult(nsres
);
2748 *p
= b
? VARIANT_TRUE
: VARIANT_FALSE
;
2752 static HRESULT WINAPI
DOMProgressEvent_get_loaded(IDOMProgressEvent
*iface
, ULONGLONG
*p
)
2754 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2756 TRACE("(%p)->(%p)\n", This
, p
);
2758 return map_nsresult(nsIDOMProgressEvent_GetLoaded(This
->nsevent
, p
));
2761 static HRESULT WINAPI
DOMProgressEvent_get_total(IDOMProgressEvent
*iface
, ULONGLONG
*p
)
2763 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2766 TRACE("(%p)->(%p)\n", This
, p
);
2768 if(!This
->manual_init
&& (NS_FAILED(nsIDOMProgressEvent_GetLengthComputable(This
->nsevent
, &b
)) || !b
)) {
2773 return map_nsresult(nsIDOMProgressEvent_GetTotal(This
->nsevent
, p
));
2776 static HRESULT WINAPI
DOMProgressEvent_initProgressEvent(IDOMProgressEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
2777 VARIANT_BOOL cancelable
, VARIANT_BOOL lengthComputable
,
2778 ULONGLONG loaded
, ULONGLONG total
)
2780 DOMProgressEvent
*This
= impl_from_IDOMProgressEvent(iface
);
2785 TRACE("(%p)->(%s %x %x %x %s %s)\n", This
, debugstr_w(type
), can_bubble
, cancelable
, lengthComputable
,
2786 wine_dbgstr_longlong(loaded
), wine_dbgstr_longlong(total
));
2788 if(This
->event
.target
) {
2789 TRACE("called on already dispatched event\n");
2793 hres
= IDOMEvent_initEvent(&This
->event
.IDOMEvent_iface
, type
, can_bubble
, cancelable
);
2794 if(SUCCEEDED(hres
)) {
2795 nsAString_InitDepend(&type_str
, type
);
2796 nsres
= nsIDOMProgressEvent_InitProgressEvent(This
->nsevent
, &type_str
, !!can_bubble
, !!cancelable
,
2797 !!lengthComputable
, loaded
, total
);
2798 nsAString_Finish(&type_str
);
2799 if(NS_FAILED(nsres
))
2800 return map_nsresult(nsres
);
2801 This
->manual_init
= TRUE
;
2807 static const IDOMProgressEventVtbl DOMProgressEventVtbl
= {
2808 DOMProgressEvent_QueryInterface
,
2809 DOMProgressEvent_AddRef
,
2810 DOMProgressEvent_Release
,
2811 DOMProgressEvent_GetTypeInfoCount
,
2812 DOMProgressEvent_GetTypeInfo
,
2813 DOMProgressEvent_GetIDsOfNames
,
2814 DOMProgressEvent_Invoke
,
2815 DOMProgressEvent_get_lengthComputable
,
2816 DOMProgressEvent_get_loaded
,
2817 DOMProgressEvent_get_total
,
2818 DOMProgressEvent_initProgressEvent
2821 static DOMProgressEvent
*DOMProgressEvent_from_DOMEvent(DOMEvent
*event
)
2823 return CONTAINING_RECORD(event
, DOMProgressEvent
, event
);
2826 static void *DOMProgressEvent_query_interface(DispatchEx
*dispex
, REFIID riid
)
2828 DOMProgressEvent
*This
= DOMProgressEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
2830 if(IsEqualGUID(&IID_IDOMProgressEvent
, riid
))
2831 return &This
->IDOMProgressEvent_iface
;
2832 return DOMEvent_query_interface(&This
->event
.dispex
, riid
);
2835 static void DOMProgressEvent_traverse(DispatchEx
*dispex
, nsCycleCollectionTraversalCallback
*cb
)
2837 DOMProgressEvent
*This
= DOMProgressEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
2838 DOMEvent_traverse(&This
->event
.dispex
, cb
);
2840 note_cc_edge((nsISupports
*)This
->nsevent
, "ProgressEvent.nsevent", cb
);
2843 static void DOMProgressEvent_unlink(DispatchEx
*dispex
)
2845 DOMProgressEvent
*This
= DOMProgressEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
2846 DOMEvent_unlink(&This
->event
.dispex
);
2847 unlink_ref(&This
->nsevent
);
2852 IDOMStorageEvent IDOMStorageEvent_iface
;
2859 static inline DOMStorageEvent
*impl_from_IDOMStorageEvent(IDOMStorageEvent
*iface
)
2861 return CONTAINING_RECORD(iface
, DOMStorageEvent
, IDOMStorageEvent_iface
);
2864 static HRESULT WINAPI
DOMStorageEvent_QueryInterface(IDOMStorageEvent
*iface
, REFIID riid
, void **ppv
)
2866 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2867 return IDOMEvent_QueryInterface(&This
->event
.IDOMEvent_iface
, riid
, ppv
);
2870 static ULONG WINAPI
DOMStorageEvent_AddRef(IDOMStorageEvent
*iface
)
2872 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2873 return IDOMEvent_AddRef(&This
->event
.IDOMEvent_iface
);
2876 static ULONG WINAPI
DOMStorageEvent_Release(IDOMStorageEvent
*iface
)
2878 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2879 return IDOMEvent_Release(&This
->event
.IDOMEvent_iface
);
2882 static HRESULT WINAPI
DOMStorageEvent_GetTypeInfoCount(IDOMStorageEvent
*iface
, UINT
*pctinfo
)
2884 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2885 return IDispatchEx_GetTypeInfoCount(&This
->event
.dispex
.IDispatchEx_iface
, pctinfo
);
2888 static HRESULT WINAPI
DOMStorageEvent_GetTypeInfo(IDOMStorageEvent
*iface
, UINT iTInfo
,
2889 LCID lcid
, ITypeInfo
**ppTInfo
)
2891 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2892 return IDispatchEx_GetTypeInfo(&This
->event
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
2895 static HRESULT WINAPI
DOMStorageEvent_GetIDsOfNames(IDOMStorageEvent
*iface
, REFIID riid
,
2896 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2898 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2899 return IDispatchEx_GetIDsOfNames(&This
->event
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
2903 static HRESULT WINAPI
DOMStorageEvent_Invoke(IDOMStorageEvent
*iface
, DISPID dispIdMember
,
2904 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2905 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2907 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2908 return IDispatchEx_Invoke(&This
->event
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
,
2909 wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2912 static HRESULT WINAPI
DOMStorageEvent_get_key(IDOMStorageEvent
*iface
, BSTR
*p
)
2914 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2916 TRACE("(%p)->(%p)\n", This
, p
);
2919 return (*p
= SysAllocStringLen(This
->key
, SysStringLen(This
->key
))) ? S_OK
: E_OUTOFMEMORY
;
2924 static HRESULT WINAPI
DOMStorageEvent_get_oldValue(IDOMStorageEvent
*iface
, BSTR
*p
)
2926 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2928 TRACE("(%p)->(%p)\n", This
, p
);
2931 return (*p
= SysAllocStringLen(This
->old_value
, SysStringLen(This
->old_value
))) ? S_OK
: E_OUTOFMEMORY
;
2936 static HRESULT WINAPI
DOMStorageEvent_get_newValue(IDOMStorageEvent
*iface
, BSTR
*p
)
2938 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2940 TRACE("(%p)->(%p)\n", This
, p
);
2943 return (*p
= SysAllocStringLen(This
->new_value
, SysStringLen(This
->new_value
))) ? S_OK
: E_OUTOFMEMORY
;
2948 static HRESULT WINAPI
DOMStorageEvent_get_url(IDOMStorageEvent
*iface
, BSTR
*p
)
2950 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2952 TRACE("(%p)->(%p)\n", This
, p
);
2955 return (*p
= SysAllocStringLen(This
->url
, SysStringLen(This
->url
))) ? S_OK
: E_OUTOFMEMORY
;
2960 static HRESULT WINAPI
DOMStorageEvent_get_storageArea(IDOMStorageEvent
*iface
, IHTMLStorage
**p
)
2962 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2963 FIXME("(%p)->(%p)\n", This
, p
);
2967 static HRESULT WINAPI
DOMStorageEvent_initStorageEvent(IDOMStorageEvent
*iface
, BSTR type
, VARIANT_BOOL can_bubble
,
2968 VARIANT_BOOL cancelable
, BSTR keyArg
, BSTR oldValueArg
,
2969 BSTR newValueArg
, BSTR urlArg
, IHTMLStorage
*storageAreaArg
)
2971 DOMStorageEvent
*This
= impl_from_IDOMStorageEvent(iface
);
2972 FIXME("(%p)->(%s %x %x %s %s %s %s %p)\n", This
, debugstr_w(type
), can_bubble
, cancelable
,
2973 debugstr_w(keyArg
), debugstr_w(oldValueArg
), debugstr_w(newValueArg
), debugstr_w(urlArg
), storageAreaArg
);
2977 static const IDOMStorageEventVtbl DOMStorageEventVtbl
= {
2978 DOMStorageEvent_QueryInterface
,
2979 DOMStorageEvent_AddRef
,
2980 DOMStorageEvent_Release
,
2981 DOMStorageEvent_GetTypeInfoCount
,
2982 DOMStorageEvent_GetTypeInfo
,
2983 DOMStorageEvent_GetIDsOfNames
,
2984 DOMStorageEvent_Invoke
,
2985 DOMStorageEvent_get_key
,
2986 DOMStorageEvent_get_oldValue
,
2987 DOMStorageEvent_get_newValue
,
2988 DOMStorageEvent_get_url
,
2989 DOMStorageEvent_get_storageArea
,
2990 DOMStorageEvent_initStorageEvent
2993 static DOMStorageEvent
*DOMStorageEvent_from_DOMEvent(DOMEvent
*event
)
2995 return CONTAINING_RECORD(event
, DOMStorageEvent
, event
);
2998 static void *DOMStorageEvent_query_interface(DispatchEx
*dispex
, REFIID riid
)
3000 DOMStorageEvent
*storage_event
= DOMStorageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
3002 if(IsEqualGUID(&IID_IDOMStorageEvent
, riid
))
3003 return &storage_event
->IDOMStorageEvent_iface
;
3004 return DOMEvent_query_interface(&storage_event
->event
.dispex
, riid
);
3007 static void DOMStorageEvent_destructor(DispatchEx
*dispex
)
3009 DOMStorageEvent
*storage_event
= DOMStorageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex
));
3010 SysFreeString(storage_event
->key
);
3011 SysFreeString(storage_event
->old_value
);
3012 SysFreeString(storage_event
->new_value
);
3013 SysFreeString(storage_event
->url
);
3014 DOMEvent_destructor(dispex
);
3017 static const dispex_static_data_vtbl_t DOMEvent_dispex_vtbl
= {
3018 .query_interface
= DOMEvent_query_interface
,
3019 .destructor
= DOMEvent_destructor
,
3020 .traverse
= DOMEvent_traverse
,
3021 .unlink
= DOMEvent_unlink
3024 static const tid_t DOMEvent_iface_tids
[] = {
3029 static dispex_static_data_t DOMEvent_dispex
= {
3031 &DOMEvent_dispex_vtbl
,
3036 static const dispex_static_data_vtbl_t DOMUIEvent_dispex_vtbl
= {
3037 .query_interface
= DOMUIEvent_query_interface
,
3038 .destructor
= DOMEvent_destructor
,
3039 .traverse
= DOMUIEvent_traverse
,
3040 .unlink
= DOMUIEvent_unlink
3043 static const tid_t DOMUIEvent_iface_tids
[] = {
3049 static dispex_static_data_t DOMUIEvent_dispex
= {
3051 &DOMUIEvent_dispex_vtbl
,
3053 DOMUIEvent_iface_tids
3056 static const dispex_static_data_vtbl_t DOMMouseEvent_dispex_vtbl
= {
3057 .query_interface
= DOMMouseEvent_query_interface
,
3058 .destructor
= DOMEvent_destructor
,
3059 .traverse
= DOMMouseEvent_traverse
,
3060 .unlink
= DOMMouseEvent_unlink
3063 static const tid_t DOMMouseEvent_iface_tids
[] = {
3070 static dispex_static_data_t DOMMouseEvent_dispex
= {
3072 &DOMMouseEvent_dispex_vtbl
,
3073 DispDOMMouseEvent_tid
,
3074 DOMMouseEvent_iface_tids
3077 static const dispex_static_data_vtbl_t DOMKeyboardEvent_dispex_vtbl
= {
3078 .query_interface
= DOMKeyboardEvent_query_interface
,
3079 .destructor
= DOMEvent_destructor
,
3080 .traverse
= DOMKeyboardEvent_traverse
,
3081 .unlink
= DOMKeyboardEvent_unlink
3084 static const tid_t DOMKeyboardEvent_iface_tids
[] = {
3087 IDOMKeyboardEvent_tid
,
3091 static dispex_static_data_t DOMKeyboardEvent_dispex
= {
3093 &DOMKeyboardEvent_dispex_vtbl
,
3094 DispDOMKeyboardEvent_tid
,
3095 DOMKeyboardEvent_iface_tids
3098 static void DOMPageTransitionEvent_init_dispex_info(dispex_data_t
*info
, compat_mode_t mode
)
3100 if(mode
>= COMPAT_MODE_IE11
)
3101 dispex_info_add_interface(info
, IWinePageTransitionEvent_tid
, NULL
);
3104 static const dispex_static_data_vtbl_t DOMPageTransitionEvent_dispex_vtbl
= {
3105 .query_interface
= DOMPageTransitionEvent_query_interface
,
3106 .destructor
= DOMEvent_destructor
,
3107 .traverse
= DOMEvent_traverse
,
3108 .unlink
= DOMEvent_unlink
3111 static dispex_static_data_t DOMPageTransitionEvent_dispex
= {
3112 "PageTransitionEvent",
3113 &DOMPageTransitionEvent_dispex_vtbl
,
3115 DOMEvent_iface_tids
,
3116 DOMPageTransitionEvent_init_dispex_info
3119 static const dispex_static_data_vtbl_t DOMCustomEvent_dispex_vtbl
= {
3120 .query_interface
= DOMCustomEvent_query_interface
,
3121 .destructor
= DOMCustomEvent_destructor
,
3122 .traverse
= DOMCustomEvent_traverse
,
3123 .unlink
= DOMCustomEvent_unlink
3126 static const tid_t DOMCustomEvent_iface_tids
[] = {
3128 IDOMCustomEvent_tid
,
3132 static dispex_static_data_t DOMCustomEvent_dispex
= {
3134 &DOMCustomEvent_dispex_vtbl
,
3135 DispDOMCustomEvent_tid
,
3136 DOMCustomEvent_iface_tids
3139 static const dispex_static_data_vtbl_t DOMMessageEvent_dispex_vtbl
= {
3140 .query_interface
= DOMMessageEvent_query_interface
,
3141 .destructor
= DOMMessageEvent_destructor
,
3142 .traverse
= DOMMessageEvent_traverse
,
3143 .unlink
= DOMMessageEvent_unlink
3146 static const tid_t DOMMessageEvent_iface_tids
[] = {
3151 static dispex_static_data_t DOMMessageEvent_dispex
= {
3153 &DOMMessageEvent_dispex_vtbl
,
3154 DispDOMMessageEvent_tid
,
3155 DOMMessageEvent_iface_tids
,
3156 DOMMessageEvent_init_dispex_info
3159 static const dispex_static_data_vtbl_t DOMProgressEvent_dispex_vtbl
= {
3160 .query_interface
= DOMProgressEvent_query_interface
,
3161 .destructor
= DOMEvent_destructor
,
3162 .traverse
= DOMProgressEvent_traverse
,
3163 .unlink
= DOMProgressEvent_unlink
3166 static const tid_t DOMProgressEvent_iface_tids
[] = {
3168 IDOMProgressEvent_tid
,
3172 static dispex_static_data_t DOMProgressEvent_dispex
= {
3174 &DOMProgressEvent_dispex_vtbl
,
3175 DispDOMProgressEvent_tid
,
3176 DOMProgressEvent_iface_tids
3179 static const dispex_static_data_vtbl_t DOMStorageEvent_dispex_vtbl
= {
3180 .query_interface
= DOMStorageEvent_query_interface
,
3181 .destructor
= DOMStorageEvent_destructor
,
3182 .traverse
= DOMEvent_traverse
,
3183 .unlink
= DOMEvent_unlink
3186 static const tid_t DOMStorageEvent_iface_tids
[] = {
3188 IDOMStorageEvent_tid
,
3192 static dispex_static_data_t DOMStorageEvent_dispex
= {
3194 &DOMStorageEvent_dispex_vtbl
,
3195 DispDOMStorageEvent_tid
,
3196 DOMStorageEvent_iface_tids
3199 static void *event_ctor(unsigned size
, dispex_static_data_t
*dispex_data
, nsIDOMEvent
*nsevent
, eventid_t event_id
,
3200 compat_mode_t compat_mode
)
3202 DOMEvent
*event
= calloc(1, size
);
3206 event
->IDOMEvent_iface
.lpVtbl
= &DOMEventVtbl
;
3207 event
->event_id
= event_id
;
3208 if(event_id
!= EVENTID_LAST
) {
3209 event
->type
= wcsdup(event_info
[event_id
].name
);
3214 event
->bubbles
= (event_info
[event_id
].flags
& EVENT_BUBBLES
) != 0;
3215 event
->cancelable
= (event_info
[event_id
].flags
& EVENT_CANCELABLE
) != 0;
3217 nsIDOMEvent_AddRef(event
->nsevent
= nsevent
);
3219 event
->time_stamp
= get_time_stamp();
3221 init_dispatch(&event
->dispex
, dispex_data
, compat_mode
);
3225 static void fill_parent_ui_event(nsIDOMEvent
*nsevent
, DOMUIEvent
*ui_event
)
3227 ui_event
->IDOMUIEvent_iface
.lpVtbl
= &DOMUIEventVtbl
;
3228 nsIDOMEvent_QueryInterface(nsevent
, &IID_nsIDOMUIEvent
, (void**)&ui_event
->nsevent
);
3231 static DOMEvent
*generic_event_ctor(void *iface
, nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3233 return event_ctor(sizeof(DOMEvent
), &DOMEvent_dispex
, nsevent
, event_id
, compat_mode
);
3236 static DOMEvent
*ui_event_ctor(void *iface
, nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3238 DOMUIEvent
*ui_event
= event_ctor(sizeof(DOMUIEvent
), &DOMUIEvent_dispex
, nsevent
, event_id
, compat_mode
);
3239 if(!ui_event
) return NULL
;
3240 ui_event
->IDOMUIEvent_iface
.lpVtbl
= &DOMUIEventVtbl
;
3241 ui_event
->nsevent
= iface
;
3242 return &ui_event
->event
;
3245 static DOMEvent
*mouse_event_ctor(void *iface
, nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3247 DOMMouseEvent
*mouse_event
= event_ctor(sizeof(DOMMouseEvent
), &DOMMouseEvent_dispex
, nsevent
, event_id
, compat_mode
);
3248 if(!mouse_event
) return NULL
;
3249 mouse_event
->IDOMMouseEvent_iface
.lpVtbl
= &DOMMouseEventVtbl
;
3250 mouse_event
->nsevent
= iface
;
3251 fill_parent_ui_event(nsevent
, &mouse_event
->ui_event
);
3252 return &mouse_event
->ui_event
.event
;
3255 static DOMEvent
*keyboard_event_ctor(void *iface
, nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3257 DOMKeyboardEvent
*keyboard_event
= event_ctor(sizeof(DOMKeyboardEvent
), &DOMKeyboardEvent_dispex
, nsevent
, event_id
, compat_mode
);
3258 if(!keyboard_event
) return NULL
;
3259 keyboard_event
->IDOMKeyboardEvent_iface
.lpVtbl
= &DOMKeyboardEventVtbl
;
3260 keyboard_event
->nsevent
= iface
;
3261 fill_parent_ui_event(nsevent
, &keyboard_event
->ui_event
);
3262 return &keyboard_event
->ui_event
.event
;
3265 static DOMEvent
*page_transition_event_ctor(void *iface
, nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3267 DOMPageTransitionEvent
*page_transition_event
= event_ctor(sizeof(DOMCustomEvent
), &DOMPageTransitionEvent_dispex
, nsevent
, event_id
, compat_mode
);
3268 if(!page_transition_event
) return NULL
;
3269 page_transition_event
->IWinePageTransitionEvent_iface
.lpVtbl
= &DOMPageTransitionEventVtbl
;
3270 return &page_transition_event
->event
;
3273 static DOMEvent
*custom_event_ctor(void *iface
, nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3275 DOMCustomEvent
*custom_event
= event_ctor(sizeof(DOMCustomEvent
), &DOMCustomEvent_dispex
, nsevent
, event_id
, compat_mode
);
3276 if(!custom_event
) return NULL
;
3277 custom_event
->IDOMCustomEvent_iface
.lpVtbl
= &DOMCustomEventVtbl
;
3278 nsIDOMCustomEvent_Release(iface
);
3279 return &custom_event
->event
;
3282 static DOMEvent
*progress_event_ctor(void *iface
, nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3284 DOMProgressEvent
*progress_event
;
3286 if(!(progress_event
= event_ctor(sizeof(DOMProgressEvent
), &DOMProgressEvent_dispex
, nsevent
, event_id
, compat_mode
)))
3288 progress_event
->IDOMProgressEvent_iface
.lpVtbl
= &DOMProgressEventVtbl
;
3289 progress_event
->nsevent
= iface
;
3290 return &progress_event
->event
;
3293 static DOMEvent
*message_event_ctor(void *iface
, nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3295 DOMMessageEvent
*message_event
= event_ctor(sizeof(DOMMessageEvent
), &DOMMessageEvent_dispex
, nsevent
, event_id
, compat_mode
);
3296 if(!message_event
) return NULL
;
3297 message_event
->IDOMMessageEvent_iface
.lpVtbl
= &DOMMessageEventVtbl
;
3298 return &message_event
->event
;
3301 static DOMEvent
*storage_event_ctor(void *iface
, nsIDOMEvent
*nsevent
, eventid_t event_id
, compat_mode_t compat_mode
)
3303 DOMStorageEvent
*storage_event
= event_ctor(sizeof(DOMStorageEvent
), &DOMStorageEvent_dispex
, nsevent
, event_id
, compat_mode
);
3304 if(!storage_event
) return NULL
;
3305 storage_event
->IDOMStorageEvent_iface
.lpVtbl
= &DOMStorageEventVtbl
;
3306 return &storage_event
->event
;
3309 static const struct {
3311 DOMEvent
*(*ctor
)(void *iface
, nsIDOMEvent
*nsevent
, eventid_t
, compat_mode_t
);
3312 compat_mode_t min_compat_mode
;
3313 } event_types_ctor_table
[] = {
3314 [EVENT_TYPE_EVENT
] = { NULL
, generic_event_ctor
},
3315 [EVENT_TYPE_UIEVENT
] = { &IID_nsIDOMUIEvent
, ui_event_ctor
},
3316 [EVENT_TYPE_MOUSE
] = { &IID_nsIDOMMouseEvent
, mouse_event_ctor
},
3317 [EVENT_TYPE_KEYBOARD
] = { &IID_nsIDOMKeyEvent
, keyboard_event_ctor
},
3318 [EVENT_TYPE_CLIPBOARD
] = { NULL
, generic_event_ctor
},
3319 [EVENT_TYPE_FOCUS
] = { NULL
, generic_event_ctor
},
3320 [EVENT_TYPE_DRAG
] = { NULL
, generic_event_ctor
},
3321 [EVENT_TYPE_PAGETRANSITION
] = { NULL
, page_transition_event_ctor
},
3322 [EVENT_TYPE_CUSTOM
] = { &IID_nsIDOMCustomEvent
, custom_event_ctor
},
3323 [EVENT_TYPE_PROGRESS
] = { &IID_nsIDOMProgressEvent
, progress_event_ctor
, COMPAT_MODE_IE10
},
3324 [EVENT_TYPE_MESSAGE
] = { NULL
, message_event_ctor
},
3325 [EVENT_TYPE_STORAGE
] = { NULL
, storage_event_ctor
},
3328 static DOMEvent
*alloc_event(nsIDOMEvent
*nsevent
, compat_mode_t compat_mode
, event_type_t event_type
,
3334 if(compat_mode
< event_types_ctor_table
[event_type
].min_compat_mode
)
3335 event_type
= EVENT_TYPE_EVENT
;
3337 if(event_types_ctor_table
[event_type
].iid
)
3338 nsIDOMEvent_QueryInterface(nsevent
, event_types_ctor_table
[event_type
].iid
, &iface
);
3340 /* Transfer the iface ownership to the ctor on success */
3341 if(!(event
= event_types_ctor_table
[event_type
].ctor(iface
, nsevent
, event_id
, compat_mode
)) && iface
)
3342 nsISupports_Release(iface
);
3346 HRESULT
create_event_from_nsevent(nsIDOMEvent
*nsevent
, compat_mode_t compat_mode
, DOMEvent
**ret_event
)
3348 event_type_t event_type
= EVENT_TYPE_EVENT
;
3349 eventid_t event_id
= EVENTID_LAST
;
3355 nsAString_Init(&nsstr
, NULL
);
3356 nsres
= nsIDOMEvent_GetType(nsevent
, &nsstr
);
3357 if(NS_SUCCEEDED(nsres
)) {
3359 nsAString_GetData(&nsstr
, &type
);
3360 event_id
= str_to_eid(type
);
3361 if(event_id
== EVENTID_LAST
)
3362 FIXME("unknown event type %s\n", debugstr_w(type
));
3364 ERR("GetType failed: %08lx\n", nsres
);
3366 nsAString_Finish(&nsstr
);
3368 for(i
= 0; i
< ARRAY_SIZE(event_types_ctor_table
); i
++) {
3370 if(event_types_ctor_table
[i
].iid
&&
3371 nsIDOMEvent_QueryInterface(nsevent
, event_types_ctor_table
[i
].iid
, &iface
) == NS_OK
) {
3372 nsISupports_Release(iface
);
3378 event
= alloc_event(nsevent
, compat_mode
, event_type
, event_id
);
3380 return E_OUTOFMEMORY
;
3382 event
->trusted
= TRUE
;
3387 HRESULT
create_document_event_str(HTMLDocumentNode
*doc
, const WCHAR
*type
, IDOMEvent
**ret_event
)
3389 event_type_t event_type
= EVENT_TYPE_EVENT
;
3390 nsIDOMEvent
*nsevent
;
3396 nsAString_InitDepend(&nsstr
, type
);
3397 nsres
= nsIDOMDocument_CreateEvent(doc
->dom_document
, &nsstr
, &nsevent
);
3398 nsAString_Finish(&nsstr
);
3399 if(NS_FAILED(nsres
)) {
3400 FIXME("CreateEvent(%s) failed: %08lx\n", debugstr_w(type
), nsres
);
3404 for(i
= 0; i
< ARRAY_SIZE(event_types
); i
++) {
3405 if(!wcsicmp(type
, event_types
[i
])) {
3411 event
= alloc_event(nsevent
, dispex_compat_mode(&doc
->node
.event_target
.dispex
),
3412 event_type
, EVENTID_LAST
);
3413 nsIDOMEvent_Release(nsevent
);
3415 return E_OUTOFMEMORY
;
3417 *ret_event
= &event
->IDOMEvent_iface
;
3421 HRESULT
create_document_event(HTMLDocumentNode
*doc
, eventid_t event_id
, DOMEvent
**ret_event
)
3423 nsIDOMEvent
*nsevent
;
3428 nsAString_InitDepend(&nsstr
, event_types
[event_info
[event_id
].type
]);
3429 nsres
= nsIDOMDocument_CreateEvent(doc
->dom_document
, &nsstr
, &nsevent
);
3430 nsAString_Finish(&nsstr
);
3431 if(NS_FAILED(nsres
)) {
3432 FIXME("CreateEvent(%s) failed: %08lx\n", debugstr_w(event_types
[event_info
[event_id
].type
]), nsres
);
3436 event
= alloc_event(nsevent
, doc
->document_mode
, event_info
[event_id
].type
, event_id
);
3437 nsIDOMEvent_Release(nsevent
);
3439 return E_OUTOFMEMORY
;
3441 event
->event_id
= event_id
;
3442 event
->trusted
= TRUE
;
3447 HRESULT
create_message_event(HTMLDocumentNode
*doc
, VARIANT
*data
, DOMEvent
**ret
)
3449 DOMMessageEvent
*message_event
;
3453 hres
= create_document_event(doc
, EVENTID_MESSAGE
, &event
);
3456 message_event
= DOMMessageEvent_from_DOMEvent(event
);
3458 V_VT(&message_event
->data
) = VT_EMPTY
;
3459 hres
= VariantCopy(&message_event
->data
, data
);
3461 IDOMEvent_Release(&event
->IDOMEvent_iface
);
3469 HRESULT
create_storage_event(HTMLDocumentNode
*doc
, BSTR key
, BSTR old_value
, BSTR new_value
,
3470 const WCHAR
*url
, BOOL commit
, DOMEvent
**ret
)
3472 DOMStorageEvent
*storage_event
;
3476 hres
= create_document_event(doc
, commit
? EVENTID_STORAGECOMMIT
: EVENTID_STORAGE
, &event
);
3479 storage_event
= DOMStorageEvent_from_DOMEvent(event
);
3482 if((key
&& !(storage_event
->key
= SysAllocString(key
))) ||
3483 (old_value
&& !(storage_event
->old_value
= SysAllocString(old_value
))) ||
3484 (new_value
&& !(storage_event
->new_value
= SysAllocString(new_value
)))) {
3485 IDOMEvent_Release(&event
->IDOMEvent_iface
);
3486 return E_OUTOFMEMORY
;
3490 if(url
&& !(storage_event
->url
= SysAllocString(url
))) {
3491 IDOMEvent_Release(&event
->IDOMEvent_iface
);
3492 return E_OUTOFMEMORY
;
3499 HRESULT
call_disp_func(IDispatch
*disp
, DISPPARAMS
*dp
, VARIANT
*retv
)
3501 IDispatchEx
*dispex
;
3505 memset(&ei
, 0, sizeof(ei
));
3507 hres
= IDispatch_QueryInterface(disp
, &IID_IDispatchEx
, (void**)&dispex
);
3508 if(SUCCEEDED(hres
)) {
3509 hres
= IDispatchEx_InvokeEx(dispex
, 0, GetUserDefaultLCID(), DISPATCH_METHOD
, dp
, retv
, &ei
, NULL
);
3510 IDispatchEx_Release(dispex
);
3512 TRACE("Could not get IDispatchEx interface: %08lx\n", hres
);
3513 hres
= IDispatch_Invoke(disp
, 0, &IID_NULL
, GetUserDefaultLCID(), DISPATCH_METHOD
,
3514 dp
, retv
, &ei
, NULL
);
3520 static HRESULT
call_cp_func(IDispatch
*disp
, DISPID dispid
, IHTMLEventObj
*event_obj
, VARIANT
*retv
)
3522 DISPPARAMS dp
= {NULL
,NULL
,0,0};
3527 TRACE("%p,%ld,%p,%p\n", disp
, dispid
, event_obj
, retv
);
3530 V_VT(&event_arg
) = VT_DISPATCH
;
3531 V_DISPATCH(&event_arg
) = (IDispatch
*)event_obj
;
3532 dp
.rgvarg
= &event_arg
;
3536 memset(&ei
, 0, sizeof(ei
));
3537 return IDispatch_Invoke(disp
, dispid
, &IID_NULL
, 0, DISPATCH_METHOD
, &dp
, retv
, &ei
, &argerr
);
3540 static BOOL
use_event_quirks(EventTarget
*event_target
)
3542 return dispex_compat_mode(&event_target
->dispex
) < COMPAT_MODE_IE9
;
3545 static BOOL
is_cp_event(cp_static_data_t
*data
, DISPID dispid
)
3550 if(!data
|| dispid
== DISPID_UNKNOWN
)
3554 hres
= get_dispids(data
->tid
, &data
->id_cnt
, &data
->ids
);
3560 max
= data
->id_cnt
-1;
3563 if(data
->ids
[i
] == dispid
)
3566 if(data
->ids
[i
] < dispid
)
3575 static void call_event_handlers(EventTarget
*event_target
, DOMEvent
*event
, dispatch_mode_t dispatch_mode
)
3577 const listener_container_t
*container
= get_listener_container(event_target
, event
->type
, FALSE
);
3578 const event_target_vtbl_t
*vtbl
= dispex_get_vtbl(&event_target
->dispex
);
3579 event_listener_t
*listener
, listeners_buf
[8], *listeners
= listeners_buf
;
3580 unsigned listeners_cnt
, listeners_size
;
3581 ConnectionPointContainer
*cp_container
= NULL
;
3582 BOOL skip_onevent_listener
= FALSE
;
3586 assert(!event
->current_target
);
3587 event
->current_target
= event_target
;
3589 if(container
&& !list_empty(&container
->listeners
) && event
->phase
!= DEP_CAPTURING_PHASE
) {
3590 listener
= LIST_ENTRY(list_tail(&container
->listeners
), event_listener_t
, entry
);
3591 if(listener
&& listener
->function
&& listener
->type
== LISTENER_TYPE_ONEVENT
3592 && use_event_quirks(event_target
)) {
3593 DISPID named_arg
= DISPID_THIS
;
3595 DISPPARAMS dp
= {&arg
, &named_arg
, 1, 1};
3597 skip_onevent_listener
= TRUE
;
3599 V_VT(&arg
) = VT_DISPATCH
;
3600 V_DISPATCH(&arg
) = (IDispatch
*)&event_target
->dispex
.IDispatchEx_iface
;
3601 V_VT(&v
) = VT_EMPTY
;
3602 if(vtbl
->get_dispatch_this
)
3603 V_DISPATCH(&arg
) = vtbl
->get_dispatch_this(&event_target
->dispex
);
3604 IDispatch_AddRef(V_DISPATCH(&arg
));
3606 TRACE("%p %s >>>\n", event_target
, debugstr_w(event
->type
));
3607 hres
= call_disp_func(listener
->function
, &dp
, &v
);
3608 IDispatch_Release(V_DISPATCH(&arg
));
3611 TRACE("%p %s <<< %s\n", event_target
, debugstr_w(event
->type
), debugstr_variant(&v
));
3613 if(event
->cancelable
) {
3614 if(V_VT(&v
) == VT_BOOL
) {
3616 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
3617 }else if(V_VT(&v
) != VT_EMPTY
) {
3618 FIXME("unhandled result %s\n", debugstr_variant(&v
));
3623 WARN("%p %s <<< %08lx\n", event_target
, debugstr_w(event
->type
), hres
);
3629 listeners_size
= ARRAY_SIZE(listeners_buf
);
3632 LIST_FOR_EACH_ENTRY(listener
, &container
->listeners
, event_listener_t
, entry
) {
3633 if(!listener
->function
)
3635 switch(listener
->type
) {
3636 case LISTENER_TYPE_ONEVENT
:
3637 if(skip_onevent_listener
|| event
->phase
== DEP_CAPTURING_PHASE
)
3640 case LISTENER_TYPE_CAPTURE
:
3641 if(event
->phase
== DEP_BUBBLING_PHASE
|| dispatch_mode
== DISPATCH_LEGACY
)
3644 case LISTENER_TYPE_BUBBLE
:
3645 if(event
->phase
== DEP_CAPTURING_PHASE
|| dispatch_mode
== DISPATCH_LEGACY
)
3648 case LISTENER_TYPE_ATTACHED
:
3649 if(event
->phase
== DEP_CAPTURING_PHASE
|| dispatch_mode
== DISPATCH_STANDARD
)
3654 if(listeners_cnt
== listeners_size
) {
3655 event_listener_t
*new_listeners
;
3656 if(listeners
== listeners_buf
) {
3657 new_listeners
= malloc(listeners_size
* 2 * sizeof(*new_listeners
));
3660 memcpy(new_listeners
, listeners
, listeners_cnt
* sizeof(*listeners
));
3662 new_listeners
= realloc(listeners
, listeners_size
* 2 * sizeof(*new_listeners
));
3664 listeners
= new_listeners
;
3665 listeners_size
*= 2;
3668 listeners
[listeners_cnt
].type
= listener
->type
;
3669 IDispatch_AddRef(listeners
[listeners_cnt
].function
= listener
->function
);
3674 for(listener
= listeners
; !event
->stop_immediate_propagation
3675 && listener
< listeners
+ listeners_cnt
; listener
++) {
3676 if(listener
->type
!= LISTENER_TYPE_ATTACHED
) {
3677 DISPID named_arg
= DISPID_THIS
;
3679 DISPPARAMS dp
= {args
, &named_arg
, 2, 1};
3681 V_VT(args
) = VT_DISPATCH
;
3682 V_DISPATCH(args
) = (IDispatch
*)&event_target
->dispex
.IDispatchEx_iface
;
3683 if(vtbl
->get_dispatch_this
)
3684 V_DISPATCH(args
) = vtbl
->get_dispatch_this(&event_target
->dispex
);
3685 IDispatch_AddRef(V_DISPATCH(args
));
3687 V_VT(args
+1) = VT_DISPATCH
;
3688 V_DISPATCH(args
+1) = dispatch_mode
== DISPATCH_LEGACY
3689 ? (IDispatch
*)event
->event_obj
: (IDispatch
*)&event
->IDOMEvent_iface
;
3690 V_VT(&v
) = VT_EMPTY
;
3692 TRACE("%p %s >>>\n", event_target
, debugstr_w(event
->type
));
3693 hres
= call_disp_func(listener
->function
, &dp
, &v
);
3694 IDispatch_Release(V_DISPATCH(args
));
3697 TRACE("%p %s <<< %s\n", event_target
, debugstr_w(event
->type
),
3698 debugstr_variant(&v
));
3700 if(event
->cancelable
) {
3701 if(V_VT(&v
) == VT_BOOL
) {
3703 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
3704 }else if(V_VT(&v
) != VT_EMPTY
) {
3705 FIXME("unhandled result %s\n", debugstr_variant(&v
));
3710 WARN("%p %s <<< %08lx\n", event_target
, debugstr_w(event
->type
), hres
);
3714 DISPPARAMS dp
= {&arg
, NULL
, 1, 0};
3716 V_VT(&arg
) = VT_DISPATCH
;
3717 V_DISPATCH(&arg
) = (IDispatch
*)event
->event_obj
;
3718 V_VT(&v
) = VT_EMPTY
;
3720 TRACE("%p %s attached >>>\n", event_target
, debugstr_w(event
->type
));
3721 hres
= call_disp_func(listener
->function
, &dp
, &v
);
3723 TRACE("%p %s attached <<<\n", event_target
, debugstr_w(event
->type
));
3725 if(event
->cancelable
) {
3726 if(V_VT(&v
) == VT_BOOL
) {
3728 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
3729 }else if(V_VT(&v
) != VT_EMPTY
) {
3730 FIXME("unhandled result %s\n", debugstr_variant(&v
));
3735 WARN("%p %s attached <<< %08lx\n", event_target
, debugstr_w(event
->type
), hres
);
3740 for(listener
= listeners
; listener
< listeners
+ listeners_cnt
; listener
++)
3741 IDispatch_Release(listener
->function
);
3742 if(listeners
!= listeners_buf
)
3745 if(event
->phase
!= DEP_CAPTURING_PHASE
&& event_info
[event
->event_id
].dispid
&& vtbl
->get_cp_container
)
3746 cp_container
= vtbl
->get_cp_container(&event_target
->dispex
);
3748 if(cp_container
->cps
) {
3749 ConnectionPoint
*cp
;
3752 for(j
=0; cp_container
->cp_entries
[j
].riid
; j
++) {
3753 cp
= cp_container
->cps
+ j
;
3754 if(!cp
->sinks_size
|| !is_cp_event(cp
->data
, event_info
[event
->event_id
].dispid
))
3757 for(i
=0; i
< cp
->sinks_size
; i
++) {
3758 if(!cp
->sinks
[i
].disp
)
3761 V_VT(&v
) = VT_EMPTY
;
3763 TRACE("%p cp %s [%u] >>>\n", event_target
, debugstr_w(event
->type
), i
);
3764 hres
= call_cp_func(cp
->sinks
[i
].disp
, event_info
[event
->event_id
].dispid
,
3765 cp
->data
->pass_event_arg
? event
->event_obj
: NULL
, &v
);
3767 TRACE("%p cp %s [%u] <<<\n", event_target
, debugstr_w(event
->type
), i
);
3769 if(event
->cancelable
) {
3770 if(V_VT(&v
) == VT_BOOL
) {
3772 IDOMEvent_preventDefault(&event
->IDOMEvent_iface
);
3773 }else if(V_VT(&v
) != VT_EMPTY
) {
3774 FIXME("unhandled result %s\n", debugstr_variant(&v
));
3779 WARN("%p cp %s [%u] <<< %08lx\n", event_target
, debugstr_w(event
->type
), i
, hres
);
3784 IConnectionPointContainer_Release(&cp_container
->IConnectionPointContainer_iface
);
3787 event
->current_target
= NULL
;
3790 static HRESULT
dispatch_event_object(EventTarget
*event_target
, DOMEvent
*event
,
3791 dispatch_mode_t dispatch_mode
, VARIANT_BOOL
*r
)
3793 EventTarget
*target_chain_buf
[8], **target_chain
= target_chain_buf
;
3794 unsigned chain_cnt
, chain_buf_size
, i
;
3795 const event_target_vtbl_t
*vtbl
, *target_vtbl
;
3796 HTMLEventObj
*event_obj_ref
= NULL
;
3797 IHTMLEventObj
*prev_event
= NULL
;
3801 TRACE("(%p) %s\n", event_target
, debugstr_w(event
->type
));
3804 FIXME("Uninitialized event.\n");
3808 if(event
->current_target
) {
3809 FIXME("event is being dispatched.\n");
3813 iter
= event_target
;
3814 IEventTarget_AddRef(&event_target
->IEventTarget_iface
);
3817 chain_buf_size
= ARRAY_SIZE(target_chain_buf
);
3820 if(chain_cnt
== chain_buf_size
) {
3821 EventTarget
**new_chain
;
3822 if(target_chain
== target_chain_buf
) {
3823 new_chain
= malloc(chain_buf_size
* 2 * sizeof(*new_chain
));
3826 memcpy(new_chain
, target_chain
, chain_buf_size
* sizeof(*new_chain
));
3828 new_chain
= realloc(target_chain
, chain_buf_size
* 2 * sizeof(*new_chain
));
3832 chain_buf_size
*= 2;
3833 target_chain
= new_chain
;
3836 target_chain
[chain_cnt
++] = iter
;
3838 if(!(vtbl
= dispex_get_vtbl(&iter
->dispex
))->get_parent_event_target
)
3840 iter
= vtbl
->get_parent_event_target(&iter
->dispex
);
3843 if(!event
->event_obj
&& !event
->no_event_obj
) {
3844 event_obj_ref
= alloc_event_obj(event
, dispex_compat_mode(&event
->dispex
));
3846 event
->event_obj
= &event_obj_ref
->IHTMLEventObj_iface
;
3849 target_vtbl
= dispex_get_vtbl(&event_target
->dispex
);
3850 if(target_vtbl
->set_current_event
)
3851 prev_event
= target_vtbl
->set_current_event(&event_target
->dispex
, event
->event_obj
);
3854 IEventTarget_Release(&event
->target
->IEventTarget_iface
);
3855 event
->target
= event_target
;
3856 IEventTarget_AddRef(&event_target
->IEventTarget_iface
);
3858 event
->phase
= DEP_CAPTURING_PHASE
;
3860 while(!event
->stop_propagation
&& i
)
3861 call_event_handlers(target_chain
[i
--], event
, dispatch_mode
);
3863 if(!event
->stop_propagation
) {
3864 event
->phase
= DEP_AT_TARGET
;
3865 call_event_handlers(target_chain
[0], event
, dispatch_mode
);
3868 if(event
->bubbles
) {
3869 event
->phase
= DEP_BUBBLING_PHASE
;
3870 for(i
= 1; !event
->stop_propagation
&& i
< chain_cnt
; i
++)
3871 call_event_handlers(target_chain
[i
], event
, dispatch_mode
);
3875 *r
= variant_bool(!event
->prevent_default
);
3877 if(target_vtbl
->set_current_event
) {
3878 IHTMLEventObj
*prev
= target_vtbl
->set_current_event(&event_target
->dispex
, prev_event
);
3880 IHTMLEventObj_Release(prev
);
3884 IHTMLEventObj_Release(prev_event
);
3886 if(event_info
[event
->event_id
].flags
& EVENT_HASDEFAULTHANDLERS
) {
3887 BOOL prevent_default
= event
->prevent_default
;
3888 for(i
= 0; !prevent_default
&& i
< chain_cnt
; i
++) {
3889 vtbl
= dispex_get_vtbl(&target_chain
[i
]->dispex
);
3890 if(!vtbl
->handle_event
)
3892 hres
= vtbl
->handle_event(&target_chain
[i
]->dispex
, event
->event_id
, event
->nsevent
, &prevent_default
);
3893 if(FAILED(hres
) || event
->stop_propagation
)
3896 nsIDOMEvent_PreventDefault(event
->nsevent
);
3900 event
->prevent_default
= FALSE
;
3902 event
->event_obj
= NULL
;
3903 IHTMLEventObj_Release(&event_obj_ref
->IHTMLEventObj_iface
);
3906 for(i
= 0; i
< chain_cnt
; i
++)
3907 IEventTarget_Release(&target_chain
[i
]->IEventTarget_iface
);
3908 if(target_chain
!= target_chain_buf
)
3914 void dispatch_event(EventTarget
*event_target
, DOMEvent
*event
)
3916 dispatch_event_object(event_target
, event
, DISPATCH_BOTH
, NULL
);
3919 * We may have registered multiple Gecko listeners for the same event type,
3920 * but we already dispatched event to all relevant targets. Stop event
3921 * propagation here to avoid events being dispatched multiple times.
3923 if(event_info
[event
->event_id
].flags
& EVENT_BIND_TO_TARGET
)
3924 nsIDOMEvent_StopPropagation(event
->nsevent
);
3927 HRESULT
fire_event(HTMLDOMNode
*node
, const WCHAR
*event_name
, VARIANT
*event_var
, VARIANT_BOOL
*cancelled
)
3929 HTMLEventObj
*event_obj
= NULL
;
3931 HRESULT hres
= S_OK
;
3933 eid
= attr_to_eid(event_name
);
3934 if(eid
== EVENTID_LAST
) {
3935 WARN("unknown event %s\n", debugstr_w(event_name
));
3936 return E_INVALIDARG
;
3939 if(event_var
&& V_VT(event_var
) != VT_EMPTY
&& V_VT(event_var
) != VT_ERROR
) {
3940 if(V_VT(event_var
) != VT_DISPATCH
) {
3941 FIXME("event_var %s not supported\n", debugstr_variant(event_var
));
3945 if(V_DISPATCH(event_var
)) {
3946 IHTMLEventObj
*event_iface
;
3948 hres
= IDispatch_QueryInterface(V_DISPATCH(event_var
), &IID_IHTMLEventObj
, (void**)&event_iface
);
3950 FIXME("No IHTMLEventObj iface\n");
3954 event_obj
= unsafe_impl_from_IHTMLEventObj(event_iface
);
3956 ERR("Not our IHTMLEventObj?\n");
3957 IHTMLEventObj_Release(event_iface
);
3964 event_obj
= alloc_event_obj(NULL
, dispex_compat_mode(&node
->event_target
.dispex
));
3966 return E_OUTOFMEMORY
;
3969 if(!event_obj
->event
)
3970 hres
= create_document_event(node
->doc
, eid
, &event_obj
->event
);
3972 if(SUCCEEDED(hres
)) {
3973 event_obj
->event
->event_obj
= &event_obj
->IHTMLEventObj_iface
;
3974 dispatch_event_object(&node
->event_target
, event_obj
->event
, DISPATCH_LEGACY
, NULL
);
3975 event_obj
->event
->event_obj
= NULL
;
3978 IHTMLEventObj_Release(&event_obj
->IHTMLEventObj_iface
);
3982 *cancelled
= VARIANT_TRUE
; /* FIXME */
3986 HRESULT
ensure_doc_nsevent_handler(HTMLDocumentNode
*doc
, nsIDOMNode
*nsnode
, eventid_t eid
)
3988 TRACE("%s\n", debugstr_w(event_info
[eid
].name
));
3990 if(!doc
->dom_document
)
3994 case EVENTID_FOCUSIN
:
3995 doc
->event_vector
[eid
] = TRUE
;
3996 eid
= EVENTID_FOCUS
;
3998 case EVENTID_FOCUSOUT
:
3999 doc
->event_vector
[eid
] = TRUE
;
4006 if(event_info
[eid
].flags
& EVENT_DEFAULTLISTENER
) {
4008 }else if(!(event_info
[eid
].flags
& EVENT_BIND_TO_TARGET
)) {
4012 if(!nsnode
|| nsnode
== doc
->node
.nsnode
) {
4013 if(doc
->event_vector
[eid
])
4015 doc
->event_vector
[eid
] = TRUE
;
4018 add_nsevent_listener(doc
, nsnode
, event_info
[eid
].name
);
4022 void detach_events(HTMLDocumentNode
*doc
)
4024 if(doc
->event_vector
) {
4027 for(i
=0; i
< EVENTID_LAST
; i
++) {
4028 if(doc
->event_vector
[i
]) {
4029 detach_nsevent(doc
, event_info
[i
].name
);
4030 doc
->event_vector
[i
] = FALSE
;
4035 release_nsevents(doc
);
4038 static HRESULT
get_event_dispex_ref(EventTarget
*event_target
, eventid_t eid
, BOOL alloc
, VARIANT
**ret
)
4043 lstrcpyW(buf
+2, event_info
[eid
].name
);
4044 return dispex_get_dprop_ref(&event_target
->dispex
, buf
, alloc
, ret
);
4047 static event_listener_t
*get_onevent_listener(EventTarget
*event_target
, eventid_t eid
, BOOL alloc
)
4049 listener_container_t
*container
;
4050 event_listener_t
*listener
;
4052 container
= get_listener_container(event_target
, event_info
[eid
].name
, alloc
);
4056 LIST_FOR_EACH_ENTRY_REV(listener
, &container
->listeners
, event_listener_t
, entry
) {
4057 if(listener
->type
== LISTENER_TYPE_ONEVENT
)
4064 listener
= malloc(sizeof(*listener
));
4068 listener
->type
= LISTENER_TYPE_ONEVENT
;
4069 listener
->function
= NULL
;
4070 list_add_tail(&container
->listeners
, &listener
->entry
);
4074 static void remove_event_handler(EventTarget
*event_target
, eventid_t eid
)
4076 event_listener_t
*listener
;
4080 hres
= get_event_dispex_ref(event_target
, eid
, FALSE
, &store
);
4082 VariantClear(store
);
4084 listener
= get_onevent_listener(event_target
, eid
, FALSE
);
4085 if(listener
&& listener
->function
) {
4086 IDispatch_Release(listener
->function
);
4087 listener
->function
= NULL
;
4091 static HRESULT
set_event_handler_disp(EventTarget
*event_target
, eventid_t eid
, IDispatch
*disp
)
4093 event_listener_t
*listener
;
4095 if(event_info
[eid
].flags
& EVENT_FIXME
)
4096 FIXME("unimplemented event %s\n", debugstr_w(event_info
[eid
].name
));
4098 remove_event_handler(event_target
, eid
);
4102 listener
= get_onevent_listener(event_target
, eid
, TRUE
);
4104 return E_OUTOFMEMORY
;
4106 if(listener
->function
)
4107 IDispatch_Release(listener
->function
);
4109 IDispatch_AddRef(listener
->function
= disp
);
4113 HRESULT
set_event_handler(EventTarget
*event_target
, eventid_t eid
, VARIANT
*var
)
4117 if(use_event_quirks(event_target
)) {
4118 WARN("attempt to set to VT_EMPTY in quirks mode\n");
4123 remove_event_handler(event_target
, eid
);
4127 return set_event_handler_disp(event_target
, eid
, V_DISPATCH(var
));
4133 if(!use_event_quirks(event_target
))
4134 FIXME("Setting to string %s not supported\n", debugstr_w(V_BSTR(var
)));
4137 * Setting event handler to string is a rare case and we don't want to
4138 * complicate nor increase memory of listener_container_t for that. Instead,
4139 * we store the value in DispatchEx, which can already handle custom
4142 remove_event_handler(event_target
, eid
);
4144 hres
= get_event_dispex_ref(event_target
, eid
, TRUE
, &v
);
4148 V_BSTR(v
) = SysAllocString(V_BSTR(var
));
4150 return E_OUTOFMEMORY
;
4156 FIXME("not handler %s\n", debugstr_variant(var
));
4163 HRESULT
get_event_handler(EventTarget
*event_target
, eventid_t eid
, VARIANT
*var
)
4165 event_listener_t
*listener
;
4169 hres
= get_event_dispex_ref(event_target
, eid
, FALSE
, &v
);
4170 if(SUCCEEDED(hres
) && V_VT(v
) != VT_EMPTY
) {
4171 V_VT(var
) = VT_EMPTY
;
4172 return VariantCopy(var
, v
);
4175 listener
= get_onevent_listener(event_target
, eid
, FALSE
);
4176 if(listener
&& listener
->function
) {
4177 V_VT(var
) = VT_DISPATCH
;
4178 V_DISPATCH(var
) = listener
->function
;
4179 IDispatch_AddRef(V_DISPATCH(var
));
4181 V_VT(var
) = VT_NULL
;
4187 HRESULT
attach_event(EventTarget
*event_target
, BSTR name
, IDispatch
*disp
, VARIANT_BOOL
*res
)
4189 listener_container_t
*container
;
4190 event_listener_t
*listener
;
4194 *res
= VARIANT_FALSE
;
4198 eid
= attr_to_eid(name
);
4199 if(eid
== EVENTID_LAST
) {
4200 WARN("Unknown event\n");
4201 *res
= VARIANT_TRUE
;
4205 container
= get_listener_container(event_target
, event_info
[eid
].name
, TRUE
);
4207 return E_OUTOFMEMORY
;
4209 listener
= malloc(sizeof(*listener
));
4211 return E_OUTOFMEMORY
;
4213 listener
->type
= LISTENER_TYPE_ATTACHED
;
4214 IDispatch_AddRef(listener
->function
= disp
);
4215 if(use_event_quirks(event_target
))
4216 list_add_head(&container
->listeners
, &listener
->entry
);
4218 list_add_tail(&container
->listeners
, &listener
->entry
);
4220 *res
= VARIANT_TRUE
;
4224 HRESULT
detach_event(EventTarget
*event_target
, BSTR name
, IDispatch
*disp
)
4228 eid
= attr_to_eid(name
);
4229 if(eid
== EVENTID_LAST
) {
4230 WARN("Unknown event\n");
4234 remove_event_listener(event_target
, event_info
[eid
].name
, LISTENER_TYPE_ATTACHED
, disp
);
4238 void bind_target_event(HTMLDocumentNode
*doc
, EventTarget
*event_target
, const WCHAR
*event
, IDispatch
*disp
)
4242 TRACE("(%p %p %s %p)\n", doc
, event_target
, debugstr_w(event
), disp
);
4244 eid
= attr_to_eid(event
);
4245 if(eid
== EVENTID_LAST
) {
4246 WARN("Unsupported event %s\n", debugstr_w(event
));
4250 set_event_handler_disp(event_target
, eid
, disp
);
4253 void update_doc_cp_events(HTMLDocumentNode
*doc
, cp_static_data_t
*cp
)
4257 for(i
=0; i
< EVENTID_LAST
; i
++) {
4258 if((event_info
[i
].flags
& EVENT_DEFAULTLISTENER
) && is_cp_event(cp
, event_info
[i
].dispid
))
4259 ensure_doc_nsevent_handler(doc
, NULL
, i
);
4263 void check_event_attr(HTMLDocumentNode
*doc
, nsIDOMElement
*nselem
)
4265 nsIDOMMozNamedAttrMap
*attr_map
;
4266 const PRUnichar
*name
, *value
;
4267 nsAString name_str
, value_str
;
4268 HTMLDOMNode
*node
= NULL
;
4277 nsres
= nsIDOMElement_HasAttributes(nselem
, &has_attrs
);
4278 if(NS_FAILED(nsres
) || !has_attrs
)
4281 nsres
= nsIDOMElement_GetAttributes(nselem
, &attr_map
);
4282 if(NS_FAILED(nsres
))
4285 nsres
= nsIDOMMozNamedAttrMap_GetLength(attr_map
, &length
);
4286 assert(nsres
== NS_OK
);
4288 nsAString_Init(&name_str
, NULL
);
4289 nsAString_Init(&value_str
, NULL
);
4291 for(i
= 0; i
< length
; i
++) {
4292 nsres
= nsIDOMMozNamedAttrMap_Item(attr_map
, i
, &attr
);
4293 if(NS_FAILED(nsres
))
4296 nsres
= nsIDOMAttr_GetName(attr
, &name_str
);
4297 if(NS_FAILED(nsres
)) {
4298 nsIDOMAttr_Release(attr
);
4302 nsAString_GetData(&name_str
, &name
);
4303 eid
= attr_to_eid(name
);
4304 if(eid
== EVENTID_LAST
) {
4305 nsIDOMAttr_Release(attr
);
4309 nsres
= nsIDOMAttr_GetValue(attr
, &value_str
);
4310 nsIDOMAttr_Release(attr
);
4311 if(NS_FAILED(nsres
))
4314 nsAString_GetData(&value_str
, &value
);
4318 TRACE("%p.%s = %s\n", nselem
, debugstr_w(name
), debugstr_w(value
));
4320 disp
= script_parse_event(doc
->window
, value
);
4325 hres
= get_node((nsIDOMNode
*)nselem
, TRUE
, &node
);
4327 IDispatch_Release(disp
);
4332 set_event_handler_disp(get_node_event_prop_target(node
, eid
), eid
, disp
);
4333 IDispatch_Release(disp
);
4338 nsAString_Finish(&name_str
);
4339 nsAString_Finish(&value_str
);
4340 nsIDOMMozNamedAttrMap_Release(attr_map
);
4343 HRESULT
doc_init_events(HTMLDocumentNode
*doc
)
4348 doc
->event_vector
= calloc(EVENTID_LAST
, sizeof(BOOL
));
4349 if(!doc
->event_vector
)
4350 return E_OUTOFMEMORY
;
4354 for(i
=0; i
< EVENTID_LAST
; i
++) {
4355 if(event_info
[i
].flags
& EVENT_HASDEFAULTHANDLERS
) {
4356 hres
= ensure_doc_nsevent_handler(doc
, NULL
, i
);
4365 static inline EventTarget
*impl_from_IEventTarget(IEventTarget
*iface
)
4367 return CONTAINING_RECORD(iface
, EventTarget
, IEventTarget_iface
);
4370 static HRESULT WINAPI
EventTarget_QueryInterface(IEventTarget
*iface
, REFIID riid
, void **ppv
)
4372 EventTarget
*This
= impl_from_IEventTarget(iface
);
4373 return IDispatchEx_QueryInterface(&This
->dispex
.IDispatchEx_iface
, riid
, ppv
);
4376 static ULONG WINAPI
EventTarget_AddRef(IEventTarget
*iface
)
4378 EventTarget
*This
= impl_from_IEventTarget(iface
);
4379 return IDispatchEx_AddRef(&This
->dispex
.IDispatchEx_iface
);
4382 static ULONG WINAPI
EventTarget_Release(IEventTarget
*iface
)
4384 EventTarget
*This
= impl_from_IEventTarget(iface
);
4385 return IDispatchEx_Release(&This
->dispex
.IDispatchEx_iface
);
4388 static HRESULT WINAPI
EventTarget_GetTypeInfoCount(IEventTarget
*iface
, UINT
*pctinfo
)
4390 EventTarget
*This
= impl_from_IEventTarget(iface
);
4391 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
4394 static HRESULT WINAPI
EventTarget_GetTypeInfo(IEventTarget
*iface
, UINT iTInfo
,
4395 LCID lcid
, ITypeInfo
**ppTInfo
)
4397 EventTarget
*This
= impl_from_IEventTarget(iface
);
4398 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
4401 static HRESULT WINAPI
EventTarget_GetIDsOfNames(IEventTarget
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
4402 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
4404 EventTarget
*This
= impl_from_IEventTarget(iface
);
4405 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
,
4406 rgszNames
, cNames
, lcid
, rgDispId
);
4409 static HRESULT WINAPI
EventTarget_Invoke(IEventTarget
*iface
, DISPID dispIdMember
,
4410 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
4411 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
4413 EventTarget
*This
= impl_from_IEventTarget(iface
);
4414 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
,
4415 riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
4418 static HRESULT WINAPI
EventTarget_addEventListener(IEventTarget
*iface
, BSTR type
,
4419 IDispatch
*function
, VARIANT_BOOL capture
)
4421 EventTarget
*This
= impl_from_IEventTarget(iface
);
4422 listener_type_t listener_type
= capture
? LISTENER_TYPE_CAPTURE
: LISTENER_TYPE_BUBBLE
;
4423 listener_container_t
*container
;
4424 event_listener_t
*listener
;
4426 TRACE("(%p)->(%s %p %x)\n", This
, debugstr_w(type
), function
, capture
);
4431 container
= get_listener_container(This
, type
, TRUE
);
4433 return E_OUTOFMEMORY
;
4435 /* check for duplicates */
4436 LIST_FOR_EACH_ENTRY(listener
, &container
->listeners
, event_listener_t
, entry
) {
4437 if(listener
->type
== listener_type
&& listener
->function
== function
)
4441 listener
= malloc(sizeof(*listener
));
4443 return E_OUTOFMEMORY
;
4445 listener
->type
= listener_type
;
4446 IDispatch_AddRef(listener
->function
= function
);
4447 list_add_tail(&container
->listeners
, &listener
->entry
);
4451 static HRESULT WINAPI
EventTarget_removeEventListener(IEventTarget
*iface
, BSTR type
,
4452 IDispatch
*listener
, VARIANT_BOOL capture
)
4454 EventTarget
*This
= impl_from_IEventTarget(iface
);
4456 TRACE("(%p)->(%s %p %x)\n", This
, debugstr_w(type
), listener
, capture
);
4458 remove_event_listener(This
, type
, capture
? LISTENER_TYPE_CAPTURE
: LISTENER_TYPE_BUBBLE
, listener
);
4462 static HRESULT WINAPI
EventTarget_dispatchEvent(IEventTarget
*iface
, IDOMEvent
*event_iface
, VARIANT_BOOL
*result
)
4464 EventTarget
*This
= impl_from_IEventTarget(iface
);
4465 DOMEvent
*event
= unsafe_impl_from_IDOMEvent(event_iface
);
4467 TRACE("(%p)->(%p %p)\n", This
, event
, result
);
4470 WARN("Invalid event\n");
4471 return E_INVALIDARG
;
4474 return dispatch_event_object(This
, event
, DISPATCH_STANDARD
, result
);
4477 static HRESULT
IEventTarget_addEventListener_hook(DispatchEx
*dispex
, WORD flags
,
4478 DISPPARAMS
*dp
, VARIANT
*res
, EXCEPINFO
*ei
, IServiceProvider
*caller
)
4480 /* If only two arguments were given, implicitly set capture to false */
4481 if((flags
& DISPATCH_METHOD
) && dp
->cArgs
== 2 && !dp
->cNamedArgs
) {
4483 DISPPARAMS new_dp
= {args
, NULL
, 3, 0};
4484 V_VT(args
) = VT_BOOL
;
4485 V_BOOL(args
) = VARIANT_FALSE
;
4486 args
[1] = dp
->rgvarg
[0];
4487 args
[2] = dp
->rgvarg
[1];
4489 TRACE("implicit capture\n");
4491 return dispex_call_builtin(dispex
, DISPID_IEVENTTARGET_ADDEVENTLISTENER
, &new_dp
, res
, ei
, caller
);
4494 return S_FALSE
; /* fallback to default */
4497 static HRESULT
IEventTarget_removeEventListener_hook(DispatchEx
*dispex
, WORD flags
,
4498 DISPPARAMS
*dp
, VARIANT
*res
, EXCEPINFO
*ei
, IServiceProvider
*caller
)
4500 /* If only two arguments were given, implicitly set capture to false */
4501 if((flags
& DISPATCH_METHOD
) && dp
->cArgs
== 2 && !dp
->cNamedArgs
) {
4503 DISPPARAMS new_dp
= {args
, NULL
, 3, 0};
4504 V_VT(args
) = VT_BOOL
;
4505 V_BOOL(args
) = VARIANT_FALSE
;
4506 args
[1] = dp
->rgvarg
[0];
4507 args
[2] = dp
->rgvarg
[1];
4509 TRACE("implicit capture\n");
4511 return dispex_call_builtin(dispex
, DISPID_IEVENTTARGET_REMOVEEVENTLISTENER
, &new_dp
, res
, ei
, caller
);
4514 return S_FALSE
; /* fallback to default */
4517 static const IEventTargetVtbl EventTargetVtbl
= {
4518 EventTarget_QueryInterface
,
4520 EventTarget_Release
,
4521 EventTarget_GetTypeInfoCount
,
4522 EventTarget_GetTypeInfo
,
4523 EventTarget_GetIDsOfNames
,
4525 EventTarget_addEventListener
,
4526 EventTarget_removeEventListener
,
4527 EventTarget_dispatchEvent
4530 static EventTarget
*unsafe_impl_from_IEventTarget(IEventTarget
*iface
)
4532 return iface
&& iface
->lpVtbl
== &EventTargetVtbl
? impl_from_IEventTarget(iface
) : NULL
;
4535 static HRESULT
get_gecko_target(IEventTarget
*target
, nsIDOMEventTarget
**ret
)
4537 EventTarget
*event_target
= unsafe_impl_from_IEventTarget(target
);
4538 const event_target_vtbl_t
*vtbl
;
4542 WARN("Not our IEventTarget implementation\n");
4543 return E_INVALIDARG
;
4546 vtbl
= (const event_target_vtbl_t
*)dispex_get_vtbl(&event_target
->dispex
);
4547 nsres
= nsISupports_QueryInterface(vtbl
->get_gecko_target(&event_target
->dispex
),
4548 &IID_nsIDOMEventTarget
, (void**)ret
);
4549 assert(nsres
== NS_OK
);
4553 void *EventTarget_query_interface(EventTarget
*event_target
, REFIID riid
)
4555 if(IsEqualGUID(riid
, &IID_IEventTarget
)) {
4556 if(use_event_quirks(event_target
)) {
4557 WARN("IEventTarget queried, but not supported by in document mode\n");
4560 return &event_target
->IEventTarget_iface
;
4566 void EventTarget_init_dispex_info(dispex_data_t
*dispex_info
, compat_mode_t compat_mode
)
4568 static const dispex_hook_t IEventTarget_hooks
[] = {
4569 {DISPID_IEVENTTARGET_ADDEVENTLISTENER
, IEventTarget_addEventListener_hook
},
4570 {DISPID_IEVENTTARGET_REMOVEEVENTLISTENER
, IEventTarget_removeEventListener_hook
},
4574 if(compat_mode
>= COMPAT_MODE_IE9
)
4575 dispex_info_add_interface(dispex_info
, IEventTarget_tid
, IEventTarget_hooks
);
4578 static int event_id_cmp(const void *key
, const struct wine_rb_entry
*entry
)
4580 return wcscmp(key
, WINE_RB_ENTRY_VALUE(entry
, listener_container_t
, entry
)->type
);
4583 void EventTarget_Init(EventTarget
*event_target
, dispex_static_data_t
*dispex_data
, compat_mode_t compat_mode
)
4585 init_dispatch(&event_target
->dispex
, dispex_data
, compat_mode
);
4586 event_target
->IEventTarget_iface
.lpVtbl
= &EventTargetVtbl
;
4587 wine_rb_init(&event_target
->handler_map
, event_id_cmp
);
4590 void traverse_event_target(EventTarget
*event_target
, nsCycleCollectionTraversalCallback
*cb
)
4592 listener_container_t
*iter
;
4593 event_listener_t
*listener
;
4595 RB_FOR_EACH_ENTRY(iter
, &event_target
->handler_map
, listener_container_t
, entry
)
4596 LIST_FOR_EACH_ENTRY(listener
, &iter
->listeners
, event_listener_t
, entry
)
4597 if(listener
->function
)
4598 note_cc_edge((nsISupports
*)listener
->function
, "EventTarget.listener", cb
);
4601 void release_event_target(EventTarget
*event_target
)
4603 listener_container_t
*iter
, *iter2
;
4605 WINE_RB_FOR_EACH_ENTRY_DESTRUCTOR(iter
, iter2
, &event_target
->handler_map
, listener_container_t
, entry
) {
4606 while(!list_empty(&iter
->listeners
)) {
4607 event_listener_t
*listener
= LIST_ENTRY(list_head(&iter
->listeners
), event_listener_t
, entry
);
4608 list_remove(&listener
->entry
);
4609 if(listener
->function
)
4610 IDispatch_Release(listener
->function
);
4615 rb_destroy(&event_target
->handler_map
, NULL
, NULL
);