include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / mshtml / htmlevent.c
blob6489c557def6102521938c4ba0a11e11246bad44
1 /*
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
19 #include <stdarg.h>
21 #define COBJMACROS
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "ole2.h"
27 #include "mshtmdid.h"
28 #include "wininet.h"
30 #include "mshtml_private.h"
31 #include "htmlevent.h"
32 #include "htmlscript.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
38 typedef enum {
39 LISTENER_TYPE_CAPTURE,
40 LISTENER_TYPE_BUBBLE,
41 LISTENER_TYPE_ONEVENT,
42 LISTENER_TYPE_ATTACHED
43 } listener_type_t;
45 typedef struct {
46 struct list entry;
47 listener_type_t type;
48 IDispatch *function;
49 } event_listener_t;
51 typedef struct {
52 struct wine_rb_entry entry;
53 struct list listeners;
54 WCHAR type[1];
55 } listener_container_t;
57 typedef enum {
58 DISPATCH_BOTH,
59 DISPATCH_STANDARD,
60 DISPATCH_LEGACY
61 } dispatch_mode_t;
63 /* Keep inherited event types after the inheritor (e.g. DragEvent->MouseEvent->UIEvent) */
64 typedef enum {
65 EVENT_TYPE_EVENT,
66 EVENT_TYPE_CUSTOM,
67 EVENT_TYPE_DRAG,
68 EVENT_TYPE_KEYBOARD,
69 EVENT_TYPE_MOUSE,
70 EVENT_TYPE_FOCUS,
71 EVENT_TYPE_UIEVENT,
72 EVENT_TYPE_PAGETRANSITION,
73 EVENT_TYPE_MESSAGE,
74 EVENT_TYPE_PROGRESS,
75 EVENT_TYPE_STORAGE,
76 EVENT_TYPE_CLIPBOARD
77 } event_type_t;
79 static const WCHAR *event_types[] = {
80 L"Event",
81 L"CustomEvent",
82 L"Event", /* FIXME */
83 L"KeyboardEvent",
84 L"MouseEvent",
85 L"Event", /* FIXME */
86 L"UIEvent",
87 L"PageTransitionEvent",
88 L"MessageEvent",
89 L"ProgressEvent",
90 L"StorageEvent",
91 L"Event" /* FIXME */
94 typedef struct {
95 const WCHAR *name;
96 event_type_t type;
97 DISPID dispid;
98 DWORD flags;
99 } event_info_t;
101 /* Use Gecko default listener (it's registered on window object for DOM nodes). */
102 #define EVENT_DEFAULTLISTENER 0x0001
103 /* Register Gecko listener on target itself (unlike EVENT_DEFAULTLISTENER). */
104 #define EVENT_BIND_TO_TARGET 0x0002
105 /* Event bubbles by default (unless explicitly specified otherwise). */
106 #define EVENT_BUBBLES 0x0004
107 /* Event is cancelable by default (unless explicitly specified otherwise). */
108 #define EVENT_CANCELABLE 0x0008
109 /* Event may have default handler (so we always have to register Gecko listener). */
110 #define EVENT_HASDEFAULTHANDLERS 0x0020
111 /* Ecent is not supported properly, print FIXME message when it's used. */
112 #define EVENT_FIXME 0x0040
114 /* mouse event flags for fromElement and toElement implementation */
115 #define EVENT_MOUSE_TO_RELATED 0x0100
116 #define EVENT_MOUSE_FROM_RELATED 0x0200
118 /* Keep these sorted case sensitively */
119 static const event_info_t event_info[] = {
120 {L"DOMContentLoaded", EVENT_TYPE_EVENT, 0,
121 EVENT_DEFAULTLISTENER | EVENT_HASDEFAULTHANDLERS | EVENT_BUBBLES | EVENT_CANCELABLE },
122 {L"abort", EVENT_TYPE_EVENT, DISPID_EVMETH_ONABORT,
123 EVENT_BIND_TO_TARGET},
124 {L"afterprint", EVENT_TYPE_EVENT, DISPID_EVMETH_ONAFTERPRINT,
125 EVENT_DEFAULTLISTENER},
126 {L"animationend", EVENT_TYPE_EVENT, DISPID_EVPROP_ONANIMATIONEND,
127 EVENT_DEFAULTLISTENER | EVENT_BUBBLES},
128 {L"animationstart", EVENT_TYPE_EVENT, DISPID_EVPROP_ONANIMATIONSTART,
129 EVENT_DEFAULTLISTENER | EVENT_BUBBLES},
130 {L"beforeactivate", EVENT_TYPE_EVENT, DISPID_EVMETH_ONBEFOREACTIVATE,
131 EVENT_FIXME | EVENT_BUBBLES | EVENT_CANCELABLE},
132 {L"beforeprint", EVENT_TYPE_EVENT, DISPID_EVMETH_ONBEFOREPRINT,
133 EVENT_DEFAULTLISTENER},
134 {L"beforeunload", EVENT_TYPE_EVENT, DISPID_EVMETH_ONBEFOREUNLOAD,
135 EVENT_DEFAULTLISTENER | EVENT_CANCELABLE },
136 {L"blur", EVENT_TYPE_FOCUS, DISPID_EVMETH_ONBLUR,
137 EVENT_DEFAULTLISTENER},
138 {L"change", EVENT_TYPE_EVENT, DISPID_EVMETH_ONCHANGE,
139 EVENT_DEFAULTLISTENER | EVENT_BUBBLES},
140 {L"click", EVENT_TYPE_MOUSE, DISPID_EVMETH_ONCLICK,
141 EVENT_DEFAULTLISTENER | EVENT_HASDEFAULTHANDLERS | EVENT_BUBBLES | EVENT_CANCELABLE },
142 {L"contextmenu", EVENT_TYPE_MOUSE, DISPID_EVMETH_ONCONTEXTMENU,
143 EVENT_BUBBLES | EVENT_CANCELABLE},
144 {L"dataavailable", EVENT_TYPE_EVENT, DISPID_EVMETH_ONDATAAVAILABLE,
145 EVENT_FIXME | EVENT_BUBBLES},
146 {L"dblclick", EVENT_TYPE_MOUSE, DISPID_EVMETH_ONDBLCLICK,
147 EVENT_DEFAULTLISTENER | EVENT_BUBBLES | EVENT_CANCELABLE},
148 {L"drag", EVENT_TYPE_DRAG, DISPID_EVMETH_ONDRAG,
149 EVENT_FIXME | EVENT_BUBBLES | EVENT_CANCELABLE},
150 {L"dragstart", EVENT_TYPE_DRAG, DISPID_EVMETH_ONDRAGSTART,
151 EVENT_FIXME | EVENT_BUBBLES | EVENT_CANCELABLE},
152 {L"error", EVENT_TYPE_EVENT, DISPID_EVMETH_ONERROR,
153 EVENT_BIND_TO_TARGET},
154 {L"focus", EVENT_TYPE_FOCUS, DISPID_EVMETH_ONFOCUS,
155 EVENT_DEFAULTLISTENER},
156 {L"focusin", EVENT_TYPE_FOCUS, DISPID_EVMETH_ONFOCUSIN,
157 EVENT_BUBBLES},
158 {L"focusout", EVENT_TYPE_FOCUS, DISPID_EVMETH_ONFOCUSOUT,
159 EVENT_BUBBLES},
160 {L"help", EVENT_TYPE_EVENT, DISPID_EVMETH_ONHELP,
161 EVENT_BUBBLES | EVENT_CANCELABLE},
162 {L"input", EVENT_TYPE_EVENT, DISPID_UNKNOWN,
163 EVENT_DEFAULTLISTENER | EVENT_BUBBLES},
164 {L"keydown", EVENT_TYPE_KEYBOARD, DISPID_EVMETH_ONKEYDOWN,
165 EVENT_DEFAULTLISTENER | EVENT_HASDEFAULTHANDLERS | EVENT_BUBBLES | EVENT_CANCELABLE },
166 {L"keypress", EVENT_TYPE_KEYBOARD, DISPID_EVMETH_ONKEYPRESS,
167 EVENT_DEFAULTLISTENER | EVENT_BUBBLES | EVENT_CANCELABLE},
168 {L"keyup", EVENT_TYPE_KEYBOARD, DISPID_EVMETH_ONKEYUP,
169 EVENT_DEFAULTLISTENER | EVENT_BUBBLES | EVENT_CANCELABLE},
170 {L"load", EVENT_TYPE_UIEVENT, DISPID_EVMETH_ONLOAD,
171 EVENT_BIND_TO_TARGET},
172 {L"loadend", EVENT_TYPE_PROGRESS, DISPID_EVPROP_LOADEND,
173 EVENT_BIND_TO_TARGET},
174 {L"loadstart", EVENT_TYPE_PROGRESS, DISPID_EVPROP_LOADSTART,
175 EVENT_BIND_TO_TARGET},
176 {L"message", EVENT_TYPE_MESSAGE, DISPID_EVMETH_ONMESSAGE,
178 {L"mousedown", EVENT_TYPE_MOUSE, DISPID_EVMETH_ONMOUSEDOWN,
179 EVENT_DEFAULTLISTENER | EVENT_BUBBLES | EVENT_CANCELABLE},
180 {L"mousemove", EVENT_TYPE_MOUSE, DISPID_EVMETH_ONMOUSEMOVE,
181 EVENT_DEFAULTLISTENER | EVENT_BUBBLES | EVENT_CANCELABLE | EVENT_MOUSE_FROM_RELATED},
182 {L"mouseout", EVENT_TYPE_MOUSE, DISPID_EVMETH_ONMOUSEOUT,
183 EVENT_DEFAULTLISTENER | EVENT_BUBBLES | EVENT_CANCELABLE | EVENT_MOUSE_TO_RELATED},
184 {L"mouseover", EVENT_TYPE_MOUSE, DISPID_EVMETH_ONMOUSEOVER,
185 EVENT_DEFAULTLISTENER | EVENT_BUBBLES | EVENT_CANCELABLE | EVENT_MOUSE_FROM_RELATED},
186 {L"mouseup", EVENT_TYPE_MOUSE, DISPID_EVMETH_ONMOUSEUP,
187 EVENT_DEFAULTLISTENER | EVENT_BUBBLES | EVENT_CANCELABLE},
188 {L"mousewheel", EVENT_TYPE_MOUSE, DISPID_EVMETH_ONMOUSEWHEEL,
189 EVENT_FIXME},
190 {L"msthumbnailclick", EVENT_TYPE_MOUSE, DISPID_EVPROP_ONMSTHUMBNAILCLICK,
191 EVENT_FIXME},
192 {L"pagehide", EVENT_TYPE_PAGETRANSITION, DISPID_EVPROP_ONPAGEHIDE,
194 {L"pageshow", EVENT_TYPE_PAGETRANSITION, DISPID_EVPROP_ONPAGESHOW,
196 {L"paste", EVENT_TYPE_CLIPBOARD, DISPID_EVMETH_ONPASTE,
197 EVENT_FIXME | EVENT_BUBBLES | EVENT_CANCELABLE},
198 {L"progress", EVENT_TYPE_PROGRESS, DISPID_EVPROP_PROGRESS,
199 EVENT_BIND_TO_TARGET},
200 {L"readystatechange", EVENT_TYPE_EVENT, DISPID_EVMETH_ONREADYSTATECHANGE,
202 {L"resize", EVENT_TYPE_UIEVENT, DISPID_EVMETH_ONRESIZE,
203 EVENT_DEFAULTLISTENER},
204 {L"scroll", EVENT_TYPE_UIEVENT, DISPID_EVMETH_ONSCROLL,
205 EVENT_DEFAULTLISTENER | EVENT_BUBBLES /* FIXME: not for elements */},
206 {L"selectionchange", EVENT_TYPE_EVENT, DISPID_EVMETH_ONSELECTIONCHANGE,
207 EVENT_FIXME},
208 {L"selectstart", EVENT_TYPE_EVENT, DISPID_EVMETH_ONSELECTSTART,
209 EVENT_FIXME | EVENT_BUBBLES | EVENT_CANCELABLE},
210 {L"storage", EVENT_TYPE_STORAGE, DISPID_EVMETH_ONSTORAGE,
212 {L"storagecommit", EVENT_TYPE_STORAGE, DISPID_EVMETH_ONSTORAGECOMMIT,
214 {L"submit", EVENT_TYPE_EVENT, DISPID_EVMETH_ONSUBMIT,
215 EVENT_DEFAULTLISTENER | EVENT_HASDEFAULTHANDLERS | EVENT_BUBBLES | EVENT_CANCELABLE},
216 {L"timeout", EVENT_TYPE_PROGRESS, DISPID_EVPROP_TIMEOUT,
217 EVENT_BIND_TO_TARGET},
218 {L"unload", EVENT_TYPE_UIEVENT, DISPID_EVMETH_ONUNLOAD,
219 EVENT_BIND_TO_TARGET},
220 {L"visibilitychange", EVENT_TYPE_EVENT, DISPID_EVPROP_VISIBILITYCHANGE,
221 EVENT_FIXME | EVENT_BUBBLES},
223 /* EVENTID_LAST special entry */
224 {NULL, EVENT_TYPE_EVENT, 0, 0}
227 C_ASSERT(ARRAY_SIZE(event_info) - 1 == EVENTID_LAST);
229 static eventid_t str_to_eid(const WCHAR *str)
231 unsigned i, a = 0, b = ARRAY_SIZE(event_info) - 1;
232 int c;
234 while(a < b) {
235 i = (a + b) / 2;
236 if(!(c = wcscmp(event_info[i].name, str)))
237 return i;
238 if(c > 0) b = i;
239 else a = i + 1;
242 return EVENTID_LAST;
245 static eventid_t attr_to_eid(const WCHAR *str)
247 unsigned i, a = 0, b = ARRAY_SIZE(event_info) - 1;
248 int c;
250 if((str[0] != 'o' && str[0] != 'O') || (str[1] != 'n' && str[1] != 'N'))
251 return EVENTID_LAST;
253 while(a < b) {
254 i = (a + b) / 2;
255 if(!(c = wcscmp(event_info[i].name, str+2)))
256 return event_info[i].dispid ? i : EVENTID_LAST;
257 if(c > 0) b = i;
258 else a = i + 1;
261 return EVENTID_LAST;
264 const WCHAR *get_event_name(eventid_t eid)
266 return event_info[eid].name;
269 static listener_container_t *get_listener_container(EventTarget *event_target, const WCHAR *type, BOOL alloc)
271 const event_target_vtbl_t *vtbl;
272 listener_container_t *container;
273 struct wine_rb_entry *entry;
274 size_t type_len;
275 eventid_t eid;
277 entry = wine_rb_get(&event_target->handler_map, type);
278 if(entry)
279 return WINE_RB_ENTRY_VALUE(entry, listener_container_t, entry);
280 if(!alloc)
281 return NULL;
283 eid = str_to_eid(type);
284 if(event_info[eid].flags & EVENT_FIXME)
285 FIXME("unimplemented event %s\n", debugstr_w(event_info[eid].name));
287 type_len = lstrlenW(type);
288 container = malloc(FIELD_OFFSET(listener_container_t, type[type_len+1]));
289 if(!container)
290 return NULL;
291 memcpy(container->type, type, (type_len + 1) * sizeof(WCHAR));
292 list_init(&container->listeners);
293 vtbl = dispex_get_vtbl(&event_target->dispex);
294 if (!vtbl->bind_event)
295 FIXME("Unsupported event binding on target %p\n", event_target);
296 else if(eid != EVENTID_LAST)
297 vtbl->bind_event(&event_target->dispex, eid);
299 wine_rb_put(&event_target->handler_map, container->type, &container->entry);
300 return container;
303 static void remove_event_listener(EventTarget *event_target, const WCHAR *type_name, listener_type_t type, IDispatch *function)
305 listener_container_t *container;
306 event_listener_t *listener;
308 container = get_listener_container(event_target, type_name, FALSE);
309 if(!container)
310 return;
312 LIST_FOR_EACH_ENTRY(listener, &container->listeners, event_listener_t, entry) {
313 if(listener->function == function && listener->type == type) {
314 IDispatch_Release(listener->function);
315 list_remove(&listener->entry);
316 free(listener);
317 break;
322 static IEventTarget *get_event_target_iface(EventTarget *event_target)
324 const event_target_vtbl_t *vtbl = dispex_get_vtbl(&event_target->dispex);
325 IEventTarget *ret;
327 if(vtbl->get_dispatch_this) {
328 IDispatch *disp = vtbl->get_dispatch_this(&event_target->dispex);
329 IDispatch_QueryInterface(disp, &IID_IEventTarget, (void**)&ret);
330 }else {
331 ret = &event_target->IEventTarget_iface;
332 IEventTarget_AddRef(ret);
334 return ret;
337 static HRESULT get_gecko_target(IEventTarget*,nsIDOMEventTarget**);
339 typedef struct {
340 DOMEvent event;
341 IDOMUIEvent IDOMUIEvent_iface;
342 nsIDOMUIEvent *nsevent;
343 } DOMUIEvent;
345 static DOMUIEvent *DOMUIEvent_from_DOMEvent(DOMEvent *event)
347 return CONTAINING_RECORD(event, DOMUIEvent, event);
350 typedef struct {
351 DOMEvent event;
352 IDOMStorageEvent IDOMStorageEvent_iface;
353 BSTR key;
354 BSTR old_value;
355 BSTR new_value;
356 BSTR url;
357 } DOMStorageEvent;
359 static DOMStorageEvent *DOMStorageEvent_from_DOMEvent(DOMEvent *event)
361 return CONTAINING_RECORD(event, DOMStorageEvent, event);
364 typedef struct {
365 DispatchEx dispex;
366 IHTMLEventObj IHTMLEventObj_iface;
367 IHTMLEventObj2 IHTMLEventObj2_iface;
368 IHTMLEventObj3 IHTMLEventObj3_iface;
369 IHTMLEventObj4 IHTMLEventObj4_iface;
370 IHTMLEventObj5 IHTMLEventObj5_iface;
371 IHTMLEventObj6 IHTMLEventObj6_iface;
373 DOMEvent *event;
374 VARIANT return_value;
375 } HTMLEventObj;
377 static inline HTMLEventObj *impl_from_IHTMLEventObj(IHTMLEventObj *iface)
379 return CONTAINING_RECORD(iface, HTMLEventObj, IHTMLEventObj_iface);
382 DISPEX_IDISPATCH_IMPL(HTMLEventObj, IHTMLEventObj, impl_from_IHTMLEventObj(iface)->dispex)
384 static HRESULT WINAPI HTMLEventObj_get_srcElement(IHTMLEventObj *iface, IHTMLElement **p)
386 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
388 TRACE("(%p)->(%p)\n", This, p);
390 if(!This->event) {
391 *p = NULL;
392 return S_OK;
395 return IDOMEvent_get_srcElement(&This->event->IDOMEvent_iface, p);
398 static HRESULT WINAPI HTMLEventObj_get_altKey(IHTMLEventObj *iface, VARIANT_BOOL *p)
400 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
401 IDOMKeyboardEvent *keyboard_event;
402 IDOMMouseEvent *mouse_event;
403 cpp_bool ret = FALSE;
405 TRACE("(%p)->(%p)\n", This, p);
407 if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) {
408 HRESULT hres = IDOMMouseEvent_get_altKey(mouse_event, p);
409 IDOMMouseEvent_Release(mouse_event);
410 return hres;
413 if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMKeyboardEvent, (void**)&keyboard_event))) {
414 HRESULT hres = IDOMKeyboardEvent_get_altKey(keyboard_event, p);
415 IDOMKeyboardEvent_Release(keyboard_event);
416 return hres;
419 *p = variant_bool(ret);
420 return S_OK;
423 static HRESULT WINAPI HTMLEventObj_get_ctrlKey(IHTMLEventObj *iface, VARIANT_BOOL *p)
425 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
426 IDOMKeyboardEvent *keyboard_event;
427 IDOMMouseEvent *mouse_event;
428 cpp_bool ret = FALSE;
430 TRACE("(%p)->(%p)\n", This, p);
432 if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) {
433 HRESULT hres = IDOMMouseEvent_get_ctrlKey(mouse_event, p);
434 IDOMMouseEvent_Release(mouse_event);
435 return hres;
438 if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMKeyboardEvent, (void**)&keyboard_event))) {
439 HRESULT hres = IDOMKeyboardEvent_get_ctrlKey(keyboard_event, p);
440 IDOMKeyboardEvent_Release(keyboard_event);
441 return hres;
444 *p = variant_bool(ret);
445 return S_OK;
448 static HRESULT WINAPI HTMLEventObj_get_shiftKey(IHTMLEventObj *iface, VARIANT_BOOL *p)
450 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
451 IDOMKeyboardEvent *keyboard_event;
452 IDOMMouseEvent *mouse_event;
453 cpp_bool ret = FALSE;
455 TRACE("(%p)->(%p)\n", This, p);
457 if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) {
458 HRESULT hres = IDOMMouseEvent_get_shiftKey(mouse_event, p);
459 IDOMMouseEvent_Release(mouse_event);
460 return hres;
463 if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMKeyboardEvent, (void**)&keyboard_event))) {
464 HRESULT hres = IDOMKeyboardEvent_get_shiftKey(keyboard_event, p);
465 IDOMKeyboardEvent_Release(keyboard_event);
466 return hres;
469 *p = variant_bool(ret);
470 return S_OK;
473 static HRESULT WINAPI HTMLEventObj_put_returnValue(IHTMLEventObj *iface, VARIANT v)
475 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
477 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
479 if(V_VT(&v) != VT_BOOL) {
480 FIXME("unsupported value %s\n", debugstr_variant(&v));
481 return DISP_E_BADVARTYPE;
484 This->return_value = v;
485 if(!V_BOOL(&v) && This->event)
486 IDOMEvent_preventDefault(&This->event->IDOMEvent_iface);
487 return S_OK;
490 static HRESULT WINAPI HTMLEventObj_get_returnValue(IHTMLEventObj *iface, VARIANT *p)
492 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
494 TRACE("(%p)->(%p)\n", This, p);
496 V_VT(p) = VT_EMPTY;
497 return VariantCopy(p, &This->return_value);
500 static HRESULT WINAPI HTMLEventObj_put_cancelBubble(IHTMLEventObj *iface, VARIANT_BOOL v)
502 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
504 TRACE("(%p)->(%x)\n", This, v);
506 if(This->event)
507 IDOMEvent_stopPropagation(&This->event->IDOMEvent_iface);
508 return S_OK;
511 static HRESULT WINAPI HTMLEventObj_get_cancelBubble(IHTMLEventObj *iface, VARIANT_BOOL *p)
513 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
515 TRACE("(%p)->(%p)\n", This, p);
517 *p = variant_bool(This->event && This->event->stop_propagation);
518 return S_OK;
521 static HRESULT WINAPI HTMLEventObj_get_fromElement(IHTMLEventObj *iface, IHTMLElement **p)
523 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
524 IDOMMouseEvent *mouse_event;
526 TRACE("(%p)->(%p)\n", This, p);
528 if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) {
529 HRESULT hres = IDOMMouseEvent_get_fromElement(mouse_event, p);
530 IDOMMouseEvent_Release(mouse_event);
531 return hres;
534 *p = NULL;
535 return S_OK;
538 static HRESULT WINAPI HTMLEventObj_get_toElement(IHTMLEventObj *iface, IHTMLElement **p)
540 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
541 IDOMMouseEvent *mouse_event;
543 TRACE("(%p)->(%p)\n", This, p);
545 if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) {
546 HRESULT hres = IDOMMouseEvent_get_toElement(mouse_event, p);
547 IDOMMouseEvent_Release(mouse_event);
548 return hres;
551 *p = NULL;
552 return S_OK;
555 static HRESULT WINAPI HTMLEventObj_put_keyCode(IHTMLEventObj *iface, LONG v)
557 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
558 FIXME("(%p)->(%ld)\n", This, v);
559 return E_NOTIMPL;
562 static HRESULT WINAPI HTMLEventObj_get_keyCode(IHTMLEventObj *iface, LONG *p)
564 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
565 IDOMKeyboardEvent *keyboard_event;
567 TRACE("(%p)->(%p)\n", This, p);
569 if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMKeyboardEvent, (void**)&keyboard_event))) {
570 HRESULT hres = IDOMKeyboardEvent_get_keyCode(keyboard_event, p);
571 IDOMKeyboardEvent_Release(keyboard_event);
572 return hres;
575 *p = 0;
576 return S_OK;
579 static HRESULT WINAPI HTMLEventObj_get_button(IHTMLEventObj *iface, LONG *p)
581 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
582 IDOMMouseEvent *mouse_event;
583 USHORT button = 0;
585 TRACE("(%p)->(%p)\n", This, p);
587 if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) {
588 HRESULT hres = IDOMMouseEvent_get_button(mouse_event, &button);
589 IDOMMouseEvent_Release(mouse_event);
590 if(FAILED(hres))
591 return hres;
594 *p = button;
595 return S_OK;
598 static HRESULT WINAPI HTMLEventObj_get_type(IHTMLEventObj *iface, BSTR *p)
600 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
602 TRACE("(%p)->(%p)\n", This, p);
604 if(!This->event) {
605 *p = NULL;
606 return S_OK;
609 return IDOMEvent_get_type(&This->event->IDOMEvent_iface, p);
612 static HRESULT WINAPI HTMLEventObj_get_qualifier(IHTMLEventObj *iface, BSTR *p)
614 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
616 FIXME("(%p)->(%p)\n", This, p);
618 *p = NULL;
619 return S_OK;
622 static HRESULT WINAPI HTMLEventObj_get_reason(IHTMLEventObj *iface, LONG *p)
624 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
626 FIXME("(%p)->(%p)\n", This, p);
628 *p = 0;
629 return S_OK;
632 static HRESULT WINAPI HTMLEventObj_get_x(IHTMLEventObj *iface, LONG *p)
634 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
635 LONG x = 0;
637 TRACE("(%p)->(%p)\n", This, p);
639 if(This->event) {
640 nsIDOMUIEvent *ui_event;
641 nsresult nsres = nsIDOMEvent_QueryInterface(This->event->nsevent, &IID_nsIDOMUIEvent, (void**)&ui_event);
643 if(NS_SUCCEEDED(nsres)) {
644 /* NOTE: pageX is not exactly right here. */
645 nsres = nsIDOMUIEvent_GetPageX(ui_event, &x);
646 assert(nsres == NS_OK);
647 nsIDOMUIEvent_Release(ui_event);
651 *p = x;
652 return S_OK;
655 static HRESULT WINAPI HTMLEventObj_get_y(IHTMLEventObj *iface, LONG *p)
657 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
658 LONG y = 0;
660 TRACE("(%p)->(%p)\n", This, p);
662 if(This->event) {
663 nsIDOMUIEvent *ui_event;
664 nsresult nsres = nsIDOMEvent_QueryInterface(This->event->nsevent, &IID_nsIDOMUIEvent, (void**)&ui_event);
666 if(NS_SUCCEEDED(nsres)) {
667 /* NOTE: pageY is not exactly right here. */
668 nsres = nsIDOMUIEvent_GetPageY(ui_event, &y);
669 assert(nsres == NS_OK);
670 nsIDOMUIEvent_Release(ui_event);
674 *p = y;
675 return S_OK;
678 static HRESULT WINAPI HTMLEventObj_get_clientX(IHTMLEventObj *iface, LONG *p)
680 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
681 IDOMMouseEvent *mouse_event;
683 TRACE("(%p)->(%p)\n", This, p);
685 if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) {
686 HRESULT hres = IDOMMouseEvent_get_clientX(mouse_event, p);
687 IDOMMouseEvent_Release(mouse_event);
688 return hres;
691 *p = 0;
692 return S_OK;
695 static HRESULT WINAPI HTMLEventObj_get_clientY(IHTMLEventObj *iface, LONG *p)
697 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
698 IDOMMouseEvent *mouse_event;
700 TRACE("(%p)->(%p)\n", This, p);
702 if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) {
703 HRESULT hres = IDOMMouseEvent_get_clientY(mouse_event, p);
704 IDOMMouseEvent_Release(mouse_event);
705 return hres;
708 *p = 0;
709 return S_OK;
712 static HRESULT WINAPI HTMLEventObj_get_offsetX(IHTMLEventObj *iface, LONG *p)
714 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
715 IDOMMouseEvent *mouse_event;
717 TRACE("(%p)->(%p)\n", This, p);
719 if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) {
720 HRESULT hres = IDOMMouseEvent_get_offsetX(mouse_event, p);
721 IDOMMouseEvent_Release(mouse_event);
722 return hres;
725 *p = 0;
726 return S_OK;
729 static HRESULT WINAPI HTMLEventObj_get_offsetY(IHTMLEventObj *iface, LONG *p)
731 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
732 IDOMMouseEvent *mouse_event;
734 TRACE("(%p)->(%p)\n", This, p);
736 if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) {
737 HRESULT hres = IDOMMouseEvent_get_offsetY(mouse_event, p);
738 IDOMMouseEvent_Release(mouse_event);
739 return hres;
742 *p = 0;
743 return S_OK;
746 static HRESULT WINAPI HTMLEventObj_get_screenX(IHTMLEventObj *iface, LONG *p)
748 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
749 IDOMMouseEvent *mouse_event;
751 TRACE("(%p)->(%p)\n", This, p);
753 if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) {
754 HRESULT hres = IDOMMouseEvent_get_screenX(mouse_event, p);
755 IDOMMouseEvent_Release(mouse_event);
756 return hres;
759 *p = 0;
760 return S_OK;
763 static HRESULT WINAPI HTMLEventObj_get_screenY(IHTMLEventObj *iface, LONG *p)
765 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
766 IDOMMouseEvent *mouse_event;
768 TRACE("(%p)->(%p)\n", This, p);
770 if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) {
771 HRESULT hres = IDOMMouseEvent_get_screenY(mouse_event, p);
772 IDOMMouseEvent_Release(mouse_event);
773 return hres;
776 *p = 0;
777 return S_OK;
780 static HRESULT WINAPI HTMLEventObj_get_srcFilter(IHTMLEventObj *iface, IDispatch **p)
782 HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
784 FIXME("(%p)->(%p)\n", This, p);
786 *p = NULL;
787 return S_OK;
790 static const IHTMLEventObjVtbl HTMLEventObjVtbl = {
791 HTMLEventObj_QueryInterface,
792 HTMLEventObj_AddRef,
793 HTMLEventObj_Release,
794 HTMLEventObj_GetTypeInfoCount,
795 HTMLEventObj_GetTypeInfo,
796 HTMLEventObj_GetIDsOfNames,
797 HTMLEventObj_Invoke,
798 HTMLEventObj_get_srcElement,
799 HTMLEventObj_get_altKey,
800 HTMLEventObj_get_ctrlKey,
801 HTMLEventObj_get_shiftKey,
802 HTMLEventObj_put_returnValue,
803 HTMLEventObj_get_returnValue,
804 HTMLEventObj_put_cancelBubble,
805 HTMLEventObj_get_cancelBubble,
806 HTMLEventObj_get_fromElement,
807 HTMLEventObj_get_toElement,
808 HTMLEventObj_put_keyCode,
809 HTMLEventObj_get_keyCode,
810 HTMLEventObj_get_button,
811 HTMLEventObj_get_type,
812 HTMLEventObj_get_qualifier,
813 HTMLEventObj_get_reason,
814 HTMLEventObj_get_x,
815 HTMLEventObj_get_y,
816 HTMLEventObj_get_clientX,
817 HTMLEventObj_get_clientY,
818 HTMLEventObj_get_offsetX,
819 HTMLEventObj_get_offsetY,
820 HTMLEventObj_get_screenX,
821 HTMLEventObj_get_screenY,
822 HTMLEventObj_get_srcFilter
825 static inline HTMLEventObj *unsafe_impl_from_IHTMLEventObj(IHTMLEventObj *iface)
827 return iface->lpVtbl == &HTMLEventObjVtbl ? impl_from_IHTMLEventObj(iface) : NULL;
830 static inline HTMLEventObj *impl_from_IHTMLEventObj2(IHTMLEventObj2 *iface)
832 return CONTAINING_RECORD(iface, HTMLEventObj, IHTMLEventObj2_iface);
835 DISPEX_IDISPATCH_IMPL(HTMLEventObj2, IHTMLEventObj2, impl_from_IHTMLEventObj2(iface)->dispex)
837 static HRESULT WINAPI HTMLEventObj2_setAttribute(IHTMLEventObj2 *iface, BSTR strAttributeName, VARIANT AttributeValue, LONG lFlags)
839 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
841 FIXME("(%p)->(%s %s %08lx)\n", This, debugstr_w(strAttributeName), debugstr_variant(&AttributeValue), lFlags);
843 return E_NOTIMPL;
846 static HRESULT WINAPI HTMLEventObj2_getAttribute(IHTMLEventObj2 *iface, BSTR strAttributeName, LONG lFlags, VARIANT *AttributeValue)
848 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
850 FIXME("(%p)->(%s %08lx %p)\n", This, debugstr_w(strAttributeName), lFlags, AttributeValue);
852 return E_NOTIMPL;
855 static HRESULT WINAPI HTMLEventObj2_removeAttribute(IHTMLEventObj2 *iface, BSTR strAttributeName, LONG lFlags, VARIANT_BOOL *pfSuccess)
857 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
859 FIXME("(%p)->(%s %lx %p)\n", This, debugstr_w(strAttributeName), lFlags, pfSuccess);
861 return E_NOTIMPL;
864 static HRESULT WINAPI HTMLEventObj2_put_propertyName(IHTMLEventObj2 *iface, BSTR v)
866 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
868 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
870 return E_NOTIMPL;
873 static HRESULT WINAPI HTMLEventObj2_get_propertyName(IHTMLEventObj2 *iface, BSTR *p)
875 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
877 FIXME("(%p)->(%p)\n", This, p);
879 return E_NOTIMPL;
882 static HRESULT WINAPI HTMLEventObj2_put_bookmarks(IHTMLEventObj2 *iface, IHTMLBookmarkCollection *v)
884 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
886 FIXME("(%p)->(%p)\n", This, v);
888 return E_NOTIMPL;
891 static HRESULT WINAPI HTMLEventObj2_get_bookmarks(IHTMLEventObj2 *iface, IHTMLBookmarkCollection **p)
893 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
895 FIXME("(%p)->(%p)\n", This, p);
897 return E_NOTIMPL;
900 static HRESULT WINAPI HTMLEventObj2_put_recordset(IHTMLEventObj2 *iface, IDispatch *v)
902 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
904 FIXME("(%p)->(%p)\n", This, v);
906 return E_NOTIMPL;
909 static HRESULT WINAPI HTMLEventObj2_get_recordset(IHTMLEventObj2 *iface, IDispatch **p)
911 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
913 FIXME("(%p)->(%p)\n", This, p);
915 return E_NOTIMPL;
918 static HRESULT WINAPI HTMLEventObj2_put_dataFld(IHTMLEventObj2 *iface, BSTR v)
920 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
922 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
924 return E_NOTIMPL;
927 static HRESULT WINAPI HTMLEventObj2_get_dataFld(IHTMLEventObj2 *iface, BSTR *p)
929 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
931 FIXME("(%p)->(%p)\n", This, p);
933 return E_NOTIMPL;
936 static HRESULT WINAPI HTMLEventObj2_put_boundElements(IHTMLEventObj2 *iface, IHTMLElementCollection *v)
938 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
940 FIXME("(%p)->(%p)\n", This, v);
942 return E_NOTIMPL;
945 static HRESULT WINAPI HTMLEventObj2_get_boundElements(IHTMLEventObj2 *iface, IHTMLElementCollection **p)
947 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
949 FIXME("(%p)->(%p)\n", This, p);
951 return E_NOTIMPL;
954 static HRESULT WINAPI HTMLEventObj2_put_repeat(IHTMLEventObj2 *iface, VARIANT_BOOL v)
956 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
958 FIXME("(%p)->(%x)\n", This, v);
960 return E_NOTIMPL;
963 static HRESULT WINAPI HTMLEventObj2_get_repeat(IHTMLEventObj2 *iface, VARIANT_BOOL *p)
965 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
967 FIXME("(%p)->(%p)\n", This, p);
969 return E_NOTIMPL;
972 static HRESULT WINAPI HTMLEventObj2_put_srcUrn(IHTMLEventObj2 *iface, BSTR v)
974 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
976 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
978 return E_NOTIMPL;
981 static HRESULT WINAPI HTMLEventObj2_get_srcUrn(IHTMLEventObj2 *iface, BSTR *p)
983 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
985 FIXME("(%p)->(%p)\n", This, p);
987 return E_NOTIMPL;
990 static HRESULT WINAPI HTMLEventObj2_put_srcElement(IHTMLEventObj2 *iface, IHTMLElement *v)
992 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
994 FIXME("(%p)->(%p)\n", This, v);
996 return E_NOTIMPL;
999 static HRESULT WINAPI HTMLEventObj2_get_srcElement(IHTMLEventObj2 *iface, IHTMLElement **p)
1001 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1002 return HTMLEventObj_get_srcElement(&This->IHTMLEventObj_iface, p);
1005 static HRESULT WINAPI HTMLEventObj2_put_altKey(IHTMLEventObj2 *iface, VARIANT_BOOL v)
1007 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1009 FIXME("(%p)->(%x)\n", This, v);
1011 return E_NOTIMPL;
1014 static HRESULT WINAPI HTMLEventObj2_get_altKey(IHTMLEventObj2 *iface, VARIANT_BOOL *p)
1016 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1017 return HTMLEventObj_get_altKey(&This->IHTMLEventObj_iface, p);
1020 static HRESULT WINAPI HTMLEventObj2_put_ctrlKey(IHTMLEventObj2 *iface, VARIANT_BOOL v)
1022 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1024 FIXME("(%p)->(%x)\n", This, v);
1026 return E_NOTIMPL;
1029 static HRESULT WINAPI HTMLEventObj2_get_ctrlKey(IHTMLEventObj2 *iface, VARIANT_BOOL *p)
1031 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1032 return HTMLEventObj_get_ctrlKey(&This->IHTMLEventObj_iface, p);
1035 static HRESULT WINAPI HTMLEventObj2_put_shiftKey(IHTMLEventObj2 *iface, VARIANT_BOOL v)
1037 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1039 FIXME("(%p)->(%x)\n", This, v);
1041 return E_NOTIMPL;
1044 static HRESULT WINAPI HTMLEventObj2_get_shiftKey(IHTMLEventObj2 *iface, VARIANT_BOOL *p)
1046 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1047 return HTMLEventObj_get_shiftKey(&This->IHTMLEventObj_iface, p);
1050 static HRESULT WINAPI HTMLEventObj2_put_fromElement(IHTMLEventObj2 *iface, IHTMLElement *v)
1052 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1054 FIXME("(%p)->(%p)\n", This, v);
1056 return E_NOTIMPL;
1059 static HRESULT WINAPI HTMLEventObj2_get_fromElement(IHTMLEventObj2 *iface, IHTMLElement **p)
1061 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1062 return HTMLEventObj_get_fromElement(&This->IHTMLEventObj_iface, p);
1065 static HRESULT WINAPI HTMLEventObj2_put_toElement(IHTMLEventObj2 *iface, IHTMLElement *v)
1067 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1069 FIXME("(%p)->(%p)\n", This, v);
1071 return E_NOTIMPL;
1074 static HRESULT WINAPI HTMLEventObj2_get_toElement(IHTMLEventObj2 *iface, IHTMLElement **p)
1076 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1077 return HTMLEventObj_get_toElement(&This->IHTMLEventObj_iface, p);
1080 static HRESULT WINAPI HTMLEventObj2_put_button(IHTMLEventObj2 *iface, LONG v)
1082 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1084 FIXME("(%p)->(%ld)\n", This, v);
1086 return E_NOTIMPL;
1089 static HRESULT WINAPI HTMLEventObj2_get_button(IHTMLEventObj2 *iface, LONG *p)
1091 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1092 return HTMLEventObj_get_button(&This->IHTMLEventObj_iface, p);
1095 static HRESULT WINAPI HTMLEventObj2_put_type(IHTMLEventObj2 *iface, BSTR v)
1097 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1099 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
1101 return E_NOTIMPL;
1104 static HRESULT WINAPI HTMLEventObj2_get_type(IHTMLEventObj2 *iface, BSTR *p)
1106 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1107 return HTMLEventObj_get_type(&This->IHTMLEventObj_iface, p);
1110 static HRESULT WINAPI HTMLEventObj2_put_qualifier(IHTMLEventObj2 *iface, BSTR v)
1112 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1114 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
1116 return E_NOTIMPL;
1119 static HRESULT WINAPI HTMLEventObj2_get_qualifier(IHTMLEventObj2 *iface, BSTR *p)
1121 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1122 return HTMLEventObj_get_qualifier(&This->IHTMLEventObj_iface, p);
1125 static HRESULT WINAPI HTMLEventObj2_put_reason(IHTMLEventObj2 *iface, LONG v)
1127 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1129 FIXME("(%p)->(%ld)\n", This, v);
1131 return E_NOTIMPL;
1134 static HRESULT WINAPI HTMLEventObj2_get_reason(IHTMLEventObj2 *iface, LONG *p)
1136 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1137 return HTMLEventObj_get_reason(&This->IHTMLEventObj_iface, p);
1140 static HRESULT WINAPI HTMLEventObj2_put_x(IHTMLEventObj2 *iface, LONG v)
1142 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1144 FIXME("(%p)->(%ld)\n", This, v);
1146 return E_NOTIMPL;
1149 static HRESULT WINAPI HTMLEventObj2_get_x(IHTMLEventObj2 *iface, LONG *p)
1151 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1152 return HTMLEventObj_get_x(&This->IHTMLEventObj_iface, p);
1155 static HRESULT WINAPI HTMLEventObj2_put_y(IHTMLEventObj2 *iface, LONG v)
1157 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1159 FIXME("(%p)->(%ld)\n", This, v);
1161 return E_NOTIMPL;
1164 static HRESULT WINAPI HTMLEventObj2_get_y(IHTMLEventObj2 *iface, LONG *p)
1166 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1167 return HTMLEventObj_get_y(&This->IHTMLEventObj_iface, p);
1170 static HRESULT WINAPI HTMLEventObj2_put_clientX(IHTMLEventObj2 *iface, LONG v)
1172 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1174 FIXME("(%p)->(%ld)\n", This, v);
1176 return E_NOTIMPL;
1179 static HRESULT WINAPI HTMLEventObj2_get_clientX(IHTMLEventObj2 *iface, LONG *p)
1181 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1182 return HTMLEventObj_get_clientX(&This->IHTMLEventObj_iface, p);
1185 static HRESULT WINAPI HTMLEventObj2_put_clientY(IHTMLEventObj2 *iface, LONG v)
1187 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1189 FIXME("(%p)->(%ld)\n", This, v);
1191 return E_NOTIMPL;
1194 static HRESULT WINAPI HTMLEventObj2_get_clientY(IHTMLEventObj2 *iface, LONG *p)
1196 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1197 return HTMLEventObj_get_clientY(&This->IHTMLEventObj_iface, p);
1200 static HRESULT WINAPI HTMLEventObj2_put_offsetX(IHTMLEventObj2 *iface, LONG v)
1202 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1204 FIXME("(%p)->(%ld)\n", This, v);
1206 return E_NOTIMPL;
1209 static HRESULT WINAPI HTMLEventObj2_get_offsetX(IHTMLEventObj2 *iface, LONG *p)
1211 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1212 return HTMLEventObj_get_offsetX(&This->IHTMLEventObj_iface, p);
1215 static HRESULT WINAPI HTMLEventObj2_put_offsetY(IHTMLEventObj2 *iface, LONG v)
1217 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1219 FIXME("(%p)->(%ld)\n", This, v);
1221 return E_NOTIMPL;
1224 static HRESULT WINAPI HTMLEventObj2_get_offsetY(IHTMLEventObj2 *iface, LONG *p)
1226 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1227 return HTMLEventObj_get_offsetY(&This->IHTMLEventObj_iface, p);
1230 static HRESULT WINAPI HTMLEventObj2_put_screenX(IHTMLEventObj2 *iface, LONG v)
1232 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1234 FIXME("(%p)->(%ld)\n", This, v);
1236 return E_NOTIMPL;
1239 static HRESULT WINAPI HTMLEventObj2_get_screenX(IHTMLEventObj2 *iface, LONG *p)
1241 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1242 return HTMLEventObj_get_screenX(&This->IHTMLEventObj_iface, p);
1245 static HRESULT WINAPI HTMLEventObj2_put_screenY(IHTMLEventObj2 *iface, LONG v)
1247 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1249 FIXME("(%p)->(%ld)\n", This, v);
1251 return E_NOTIMPL;
1254 static HRESULT WINAPI HTMLEventObj2_get_screenY(IHTMLEventObj2 *iface, LONG *p)
1256 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1257 return HTMLEventObj_get_screenY(&This->IHTMLEventObj_iface, p);
1260 static HRESULT WINAPI HTMLEventObj2_put_srcFilter(IHTMLEventObj2 *iface, IDispatch *v)
1262 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1264 FIXME("(%p)->(%p)\n", This, v);
1266 return E_NOTIMPL;
1269 static HRESULT WINAPI HTMLEventObj2_get_srcFilter(IHTMLEventObj2 *iface, IDispatch **p)
1271 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1272 return HTMLEventObj_get_srcFilter(&This->IHTMLEventObj_iface, p);
1275 static HRESULT WINAPI HTMLEventObj2_get_dataTransfer(IHTMLEventObj2 *iface, IHTMLDataTransfer **p)
1277 HTMLEventObj *This = impl_from_IHTMLEventObj2(iface);
1279 FIXME("(%p)->(%p)\n", This, p);
1281 return E_NOTIMPL;
1284 static const IHTMLEventObj2Vtbl HTMLEventObj2Vtbl = {
1285 HTMLEventObj2_QueryInterface,
1286 HTMLEventObj2_AddRef,
1287 HTMLEventObj2_Release,
1288 HTMLEventObj2_GetTypeInfoCount,
1289 HTMLEventObj2_GetTypeInfo,
1290 HTMLEventObj2_GetIDsOfNames,
1291 HTMLEventObj2_Invoke,
1292 HTMLEventObj2_setAttribute,
1293 HTMLEventObj2_getAttribute,
1294 HTMLEventObj2_removeAttribute,
1295 HTMLEventObj2_put_propertyName,
1296 HTMLEventObj2_get_propertyName,
1297 HTMLEventObj2_put_bookmarks,
1298 HTMLEventObj2_get_bookmarks,
1299 HTMLEventObj2_put_recordset,
1300 HTMLEventObj2_get_recordset,
1301 HTMLEventObj2_put_dataFld,
1302 HTMLEventObj2_get_dataFld,
1303 HTMLEventObj2_put_boundElements,
1304 HTMLEventObj2_get_boundElements,
1305 HTMLEventObj2_put_repeat,
1306 HTMLEventObj2_get_repeat,
1307 HTMLEventObj2_put_srcUrn,
1308 HTMLEventObj2_get_srcUrn,
1309 HTMLEventObj2_put_srcElement,
1310 HTMLEventObj2_get_srcElement,
1311 HTMLEventObj2_put_altKey,
1312 HTMLEventObj2_get_altKey,
1313 HTMLEventObj2_put_ctrlKey,
1314 HTMLEventObj2_get_ctrlKey,
1315 HTMLEventObj2_put_shiftKey,
1316 HTMLEventObj2_get_shiftKey,
1317 HTMLEventObj2_put_fromElement,
1318 HTMLEventObj2_get_fromElement,
1319 HTMLEventObj2_put_toElement,
1320 HTMLEventObj2_get_toElement,
1321 HTMLEventObj2_put_button,
1322 HTMLEventObj2_get_button,
1323 HTMLEventObj2_put_type,
1324 HTMLEventObj2_get_type,
1325 HTMLEventObj2_put_qualifier,
1326 HTMLEventObj2_get_qualifier,
1327 HTMLEventObj2_put_reason,
1328 HTMLEventObj2_get_reason,
1329 HTMLEventObj2_put_x,
1330 HTMLEventObj2_get_x,
1331 HTMLEventObj2_put_y,
1332 HTMLEventObj2_get_y,
1333 HTMLEventObj2_put_clientX,
1334 HTMLEventObj2_get_clientX,
1335 HTMLEventObj2_put_clientY,
1336 HTMLEventObj2_get_clientY,
1337 HTMLEventObj2_put_offsetX,
1338 HTMLEventObj2_get_offsetX,
1339 HTMLEventObj2_put_offsetY,
1340 HTMLEventObj2_get_offsetY,
1341 HTMLEventObj2_put_screenX,
1342 HTMLEventObj2_get_screenX,
1343 HTMLEventObj2_put_screenY,
1344 HTMLEventObj2_get_screenY,
1345 HTMLEventObj2_put_srcFilter,
1346 HTMLEventObj2_get_srcFilter,
1347 HTMLEventObj2_get_dataTransfer
1350 static inline HTMLEventObj *impl_from_IHTMLEventObj3(IHTMLEventObj3 *iface)
1352 return CONTAINING_RECORD(iface, HTMLEventObj, IHTMLEventObj3_iface);
1355 DISPEX_IDISPATCH_IMPL(HTMLEventObj3, IHTMLEventObj3, impl_from_IHTMLEventObj3(iface)->dispex)
1357 static HRESULT WINAPI HTMLEventObj3_get_contentOverflow(IHTMLEventObj3 *iface, VARIANT_BOOL *p)
1359 HTMLEventObj *This = impl_from_IHTMLEventObj3(iface);
1361 FIXME("(%p)->(%p)\n", This, p);
1363 return E_NOTIMPL;
1366 static HRESULT WINAPI HTMLEventObj3_put_shiftLeft(IHTMLEventObj3 *iface, VARIANT_BOOL v)
1368 HTMLEventObj *This = impl_from_IHTMLEventObj3(iface);
1370 FIXME("(%p)->(%x)\n", This, v);
1372 return E_NOTIMPL;
1375 static HRESULT WINAPI HTMLEventObj3_get_shiftLeft(IHTMLEventObj3 *iface, VARIANT_BOOL *p)
1377 HTMLEventObj *This = impl_from_IHTMLEventObj3(iface);
1379 FIXME("(%p)->(%p)\n", This, p);
1381 return E_NOTIMPL;
1384 static HRESULT WINAPI HTMLEventObj3_put_altLeft(IHTMLEventObj3 *iface, VARIANT_BOOL v)
1386 HTMLEventObj *This = impl_from_IHTMLEventObj3(iface);
1388 FIXME("(%p)->(%x)\n", This, v);
1390 return E_NOTIMPL;
1393 static HRESULT WINAPI HTMLEventObj3_get_altLeft(IHTMLEventObj3 *iface, VARIANT_BOOL *p)
1395 HTMLEventObj *This = impl_from_IHTMLEventObj3(iface);
1397 FIXME("(%p)->(%p)\n", This, p);
1399 return E_NOTIMPL;
1402 static HRESULT WINAPI HTMLEventObj3_put_ctrlLeft(IHTMLEventObj3 *iface, VARIANT_BOOL v)
1404 HTMLEventObj *This = impl_from_IHTMLEventObj3(iface);
1406 FIXME("(%p)->(%x)\n", This, v);
1408 return E_NOTIMPL;
1411 static HRESULT WINAPI HTMLEventObj3_get_ctrlLeft(IHTMLEventObj3 *iface, VARIANT_BOOL *p)
1413 HTMLEventObj *This = impl_from_IHTMLEventObj3(iface);
1415 FIXME("(%p)->(%p)\n", This, p);
1417 return E_NOTIMPL;
1420 static HRESULT WINAPI HTMLEventObj3_get_imeCompositionChange(IHTMLEventObj3 *iface, LONG_PTR *p)
1422 HTMLEventObj *This = impl_from_IHTMLEventObj3(iface);
1424 FIXME("(%p)->(%p)\n", This, p);
1426 return E_NOTIMPL;
1429 static HRESULT WINAPI HTMLEventObj3_get_imeNotifyCommand(IHTMLEventObj3 *iface, LONG_PTR *p)
1431 HTMLEventObj *This = impl_from_IHTMLEventObj3(iface);
1433 FIXME("(%p)->(%p)\n", This, p);
1435 return E_NOTIMPL;
1438 static HRESULT WINAPI HTMLEventObj3_get_imeNotifyData(IHTMLEventObj3 *iface, LONG_PTR *p)
1440 HTMLEventObj *This = impl_from_IHTMLEventObj3(iface);
1442 FIXME("(%p)->(%p)\n", This, p);
1444 return E_NOTIMPL;
1447 static HRESULT WINAPI HTMLEventObj3_get_imeRequest(IHTMLEventObj3 *iface, LONG_PTR *p)
1449 HTMLEventObj *This = impl_from_IHTMLEventObj3(iface);
1451 FIXME("(%p)->(%p)\n", This, p);
1453 return E_NOTIMPL;
1456 static HRESULT WINAPI HTMLEventObj3_get_imeRequestData(IHTMLEventObj3 *iface, LONG_PTR *p)
1458 HTMLEventObj *This = impl_from_IHTMLEventObj3(iface);
1460 FIXME("(%p)->(%p)\n", This, p);
1462 return E_NOTIMPL;
1465 static HRESULT WINAPI HTMLEventObj3_get_keyboardLayout(IHTMLEventObj3 *iface, LONG_PTR *p)
1467 HTMLEventObj *This = impl_from_IHTMLEventObj3(iface);
1469 FIXME("(%p)->(%p)\n", This, p);
1471 return E_NOTIMPL;
1474 static HRESULT WINAPI HTMLEventObj3_get_behaviorCookie(IHTMLEventObj3 *iface, LONG *p)
1476 HTMLEventObj *This = impl_from_IHTMLEventObj3(iface);
1478 FIXME("(%p)->(%p)\n", This, p);
1480 return E_NOTIMPL;
1483 static HRESULT WINAPI HTMLEventObj3_get_behaviorPart(IHTMLEventObj3 *iface, LONG *p)
1485 HTMLEventObj *This = impl_from_IHTMLEventObj3(iface);
1487 FIXME("(%p)->(%p)\n", This, p);
1489 return E_NOTIMPL;
1492 static HRESULT WINAPI HTMLEventObj3_get_nextPage(IHTMLEventObj3 *iface, BSTR *p)
1494 HTMLEventObj *This = impl_from_IHTMLEventObj3(iface);
1496 FIXME("(%p)->(%p)\n", This, p);
1498 return E_NOTIMPL;
1501 static const IHTMLEventObj3Vtbl HTMLEventObj3Vtbl = {
1502 HTMLEventObj3_QueryInterface,
1503 HTMLEventObj3_AddRef,
1504 HTMLEventObj3_Release,
1505 HTMLEventObj3_GetTypeInfoCount,
1506 HTMLEventObj3_GetTypeInfo,
1507 HTMLEventObj3_GetIDsOfNames,
1508 HTMLEventObj3_Invoke,
1509 HTMLEventObj3_get_contentOverflow,
1510 HTMLEventObj3_put_shiftLeft,
1511 HTMLEventObj3_get_shiftLeft,
1512 HTMLEventObj3_put_altLeft,
1513 HTMLEventObj3_get_altLeft,
1514 HTMLEventObj3_put_ctrlLeft,
1515 HTMLEventObj3_get_ctrlLeft,
1516 HTMLEventObj3_get_imeCompositionChange,
1517 HTMLEventObj3_get_imeNotifyCommand,
1518 HTMLEventObj3_get_imeNotifyData,
1519 HTMLEventObj3_get_imeRequest,
1520 HTMLEventObj3_get_imeRequestData,
1521 HTMLEventObj3_get_keyboardLayout,
1522 HTMLEventObj3_get_behaviorCookie,
1523 HTMLEventObj3_get_behaviorPart,
1524 HTMLEventObj3_get_nextPage
1527 static inline HTMLEventObj *impl_from_IHTMLEventObj4(IHTMLEventObj4 *iface)
1529 return CONTAINING_RECORD(iface, HTMLEventObj, IHTMLEventObj4_iface);
1532 DISPEX_IDISPATCH_IMPL(HTMLEventObj4, IHTMLEventObj4, impl_from_IHTMLEventObj4(iface)->dispex)
1534 static HRESULT WINAPI HTMLEventObj4_get_wheelDelta(IHTMLEventObj4 *iface, LONG *p)
1536 HTMLEventObj *This = impl_from_IHTMLEventObj4(iface);
1538 FIXME("(%p)->(%p)\n", This, p);
1540 return E_NOTIMPL;
1543 static const IHTMLEventObj4Vtbl HTMLEventObj4Vtbl = {
1544 HTMLEventObj4_QueryInterface,
1545 HTMLEventObj4_AddRef,
1546 HTMLEventObj4_Release,
1547 HTMLEventObj4_GetTypeInfoCount,
1548 HTMLEventObj4_GetTypeInfo,
1549 HTMLEventObj4_GetIDsOfNames,
1550 HTMLEventObj4_Invoke,
1551 HTMLEventObj4_get_wheelDelta
1554 static inline HTMLEventObj *impl_from_IHTMLEventObj5(IHTMLEventObj5 *iface)
1556 return CONTAINING_RECORD(iface, HTMLEventObj, IHTMLEventObj5_iface);
1559 DISPEX_IDISPATCH_IMPL(HTMLEventObj5, IHTMLEventObj5, impl_from_IHTMLEventObj5(iface)->dispex)
1561 static HRESULT WINAPI HTMLEventObj5_put_url(IHTMLEventObj5 *iface, BSTR v)
1563 HTMLEventObj *This = impl_from_IHTMLEventObj5(iface);
1564 IDOMStorageEvent *storage_event;
1565 DOMStorageEvent *p;
1566 BSTR url;
1568 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
1570 if(!v)
1571 return E_POINTER;
1573 if(!This->event || FAILED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMStorageEvent, (void**)&storage_event)))
1574 return DISP_E_MEMBERNOTFOUND;
1575 IDOMStorageEvent_Release(storage_event);
1577 if(!(url = SysAllocString(v)))
1578 return E_OUTOFMEMORY;
1580 p = DOMStorageEvent_from_DOMEvent(This->event);
1581 SysFreeString(p->url);
1582 p->url = url;
1583 return S_OK;
1586 static HRESULT WINAPI HTMLEventObj5_get_url(IHTMLEventObj5 *iface, BSTR *p)
1588 HTMLEventObj *This = impl_from_IHTMLEventObj5(iface);
1589 IDOMStorageEvent *storage_event;
1590 HRESULT hres;
1592 TRACE("(%p)->(%p)\n", This, p);
1594 if(!This->event || FAILED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMStorageEvent, (void**)&storage_event))) {
1595 *p = NULL;
1596 return S_OK;
1599 hres = IDOMStorageEvent_get_url(storage_event, p);
1600 IDOMStorageEvent_Release(storage_event);
1601 return hres;
1604 static HRESULT WINAPI HTMLEventObj5_put_data(IHTMLEventObj5 *iface, BSTR v)
1606 HTMLEventObj *This = impl_from_IHTMLEventObj5(iface);
1608 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
1610 return E_NOTIMPL;
1613 static HRESULT WINAPI HTMLEventObj5_get_data(IHTMLEventObj5 *iface, BSTR *p)
1615 HTMLEventObj *This = impl_from_IHTMLEventObj5(iface);
1616 IDOMMessageEvent *message_event;
1617 HRESULT hres;
1619 TRACE("(%p)->(%p)\n", This, p);
1621 if(!This->event || FAILED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMessageEvent, (void**)&message_event))) {
1622 *p = NULL;
1623 return S_OK;
1626 hres = IDOMMessageEvent_get_data(message_event, p);
1627 IDOMMessageEvent_Release(message_event);
1628 return hres;
1631 static HRESULT WINAPI HTMLEventObj5_get_source(IHTMLEventObj5 *iface, IDispatch **p)
1633 HTMLEventObj *This = impl_from_IHTMLEventObj5(iface);
1634 IDOMMessageEvent *message_event;
1635 HRESULT hres;
1637 TRACE("(%p)->(%p)\n", This, p);
1639 if(!This->event || FAILED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMessageEvent, (void**)&message_event))) {
1640 *p = NULL;
1641 return S_OK;
1644 hres = IDOMMessageEvent_get_source(message_event, (IHTMLWindow2**)p);
1645 IDOMMessageEvent_Release(message_event);
1646 return hres;
1649 static HRESULT WINAPI HTMLEventObj5_put_origin(IHTMLEventObj5 *iface, BSTR v)
1651 HTMLEventObj *This = impl_from_IHTMLEventObj5(iface);
1653 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
1655 return DISP_E_MEMBERNOTFOUND;
1658 static HRESULT WINAPI HTMLEventObj5_get_origin(IHTMLEventObj5 *iface, BSTR *p)
1660 HTMLEventObj *This = impl_from_IHTMLEventObj5(iface);
1661 IDOMMessageEvent *message_event;
1662 HRESULT hres;
1664 TRACE("(%p)->(%p)\n", This, p);
1666 if(!This->event || FAILED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMessageEvent, (void**)&message_event))) {
1667 *p = NULL;
1668 return S_OK;
1671 hres = IDOMMessageEvent_get_origin(message_event, p);
1672 IDOMMessageEvent_Release(message_event);
1673 return hres;
1676 static HRESULT WINAPI HTMLEventObj5_put_issession(IHTMLEventObj5 *iface, VARIANT_BOOL v)
1678 HTMLEventObj *This = impl_from_IHTMLEventObj5(iface);
1680 FIXME("(%p)->(%x)\n", This, v);
1682 return E_NOTIMPL;
1685 static HRESULT WINAPI HTMLEventObj5_get_issession(IHTMLEventObj5 *iface, VARIANT_BOOL *p)
1687 HTMLEventObj *This = impl_from_IHTMLEventObj5(iface);
1689 FIXME("(%p)->(%p)\n", This, p);
1691 return E_NOTIMPL;
1694 static const IHTMLEventObj5Vtbl HTMLEventObj5Vtbl = {
1695 HTMLEventObj5_QueryInterface,
1696 HTMLEventObj5_AddRef,
1697 HTMLEventObj5_Release,
1698 HTMLEventObj5_GetTypeInfoCount,
1699 HTMLEventObj5_GetTypeInfo,
1700 HTMLEventObj5_GetIDsOfNames,
1701 HTMLEventObj5_Invoke,
1702 HTMLEventObj5_put_url,
1703 HTMLEventObj5_get_url,
1704 HTMLEventObj5_put_data,
1705 HTMLEventObj5_get_data,
1706 HTMLEventObj5_get_source,
1707 HTMLEventObj5_put_origin,
1708 HTMLEventObj5_get_origin,
1709 HTMLEventObj5_put_issession,
1710 HTMLEventObj5_get_issession
1713 static inline HTMLEventObj *impl_from_IHTMLEventObj6(IHTMLEventObj6 *iface)
1715 return CONTAINING_RECORD(iface, HTMLEventObj, IHTMLEventObj6_iface);
1718 DISPEX_IDISPATCH_IMPL(HTMLEventObj6, IHTMLEventObj6, impl_from_IHTMLEventObj6(iface)->dispex)
1720 static HRESULT WINAPI HTMLEventObj6_get_actionURL(IHTMLEventObj6 *iface, BSTR *p)
1722 HTMLEventObj *This = impl_from_IHTMLEventObj6(iface);
1724 FIXME("(%p)->(%p)\n", This, p);
1726 return E_NOTIMPL;
1729 static HRESULT WINAPI HTMLEventObj6_get_buttonID(IHTMLEventObj6 *iface, LONG *p)
1731 HTMLEventObj *This = impl_from_IHTMLEventObj6(iface);
1733 FIXME("(%p)->(%p)\n", This, p);
1735 return E_NOTIMPL;
1738 static const IHTMLEventObj6Vtbl HTMLEventObj6Vtbl = {
1739 HTMLEventObj6_QueryInterface,
1740 HTMLEventObj6_AddRef,
1741 HTMLEventObj6_Release,
1742 HTMLEventObj6_GetTypeInfoCount,
1743 HTMLEventObj6_GetTypeInfo,
1744 HTMLEventObj6_GetIDsOfNames,
1745 HTMLEventObj6_Invoke,
1746 HTMLEventObj6_get_actionURL,
1747 HTMLEventObj6_get_buttonID
1750 static inline HTMLEventObj *HTMLEventObj_from_DispatchEx(DispatchEx *iface)
1752 return CONTAINING_RECORD(iface, HTMLEventObj, dispex);
1755 static void *HTMLEventObj_query_interface(DispatchEx *dispex, REFIID riid)
1757 HTMLEventObj *This = HTMLEventObj_from_DispatchEx(dispex);
1759 if(IsEqualGUID(&IID_IHTMLEventObj, riid))
1760 return &This->IHTMLEventObj_iface;
1761 if(IsEqualGUID(&IID_IHTMLEventObj2, riid))
1762 return &This->IHTMLEventObj2_iface;
1763 if(IsEqualGUID(&IID_IHTMLEventObj3, riid))
1764 return &This->IHTMLEventObj3_iface;
1765 if(IsEqualGUID(&IID_IHTMLEventObj4, riid))
1766 return &This->IHTMLEventObj4_iface;
1767 if(IsEqualGUID(&IID_IHTMLEventObj5, riid))
1768 return &This->IHTMLEventObj5_iface;
1769 if(IsEqualGUID(&IID_IHTMLEventObj6, riid))
1770 return &This->IHTMLEventObj6_iface;
1772 return NULL;
1775 static void HTMLEventObj_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb)
1777 HTMLEventObj *This = HTMLEventObj_from_DispatchEx(dispex);
1778 if(This->event)
1779 note_cc_edge((nsISupports*)&This->event->IDOMEvent_iface, "event", cb);
1782 static void HTMLEventObj_unlink(DispatchEx *dispex)
1784 HTMLEventObj *This = HTMLEventObj_from_DispatchEx(dispex);
1785 if(This->event) {
1786 DOMEvent *event = This->event;
1787 This->event = NULL;
1788 IDOMEvent_Release(&event->IDOMEvent_iface);
1792 static void HTMLEventObj_destructor(DispatchEx *dispex)
1794 HTMLEventObj *This = HTMLEventObj_from_DispatchEx(dispex);
1795 free(This);
1798 static const dispex_static_data_vtbl_t HTMLEventObj_dispex_vtbl = {
1799 .query_interface = HTMLEventObj_query_interface,
1800 .destructor = HTMLEventObj_destructor,
1801 .traverse = HTMLEventObj_traverse,
1802 .unlink = HTMLEventObj_unlink
1805 static const tid_t HTMLEventObj_iface_tids[] = {
1806 IHTMLEventObj5_tid,
1807 IHTMLEventObj_tid,
1811 static dispex_static_data_t HTMLEventObj_dispex = {
1812 "MSEventObj",
1813 &HTMLEventObj_dispex_vtbl,
1814 DispCEventObj_tid,
1815 HTMLEventObj_iface_tids
1818 static HTMLEventObj *alloc_event_obj(DOMEvent *event, HTMLInnerWindow *script_global)
1820 HTMLEventObj *event_obj;
1822 event_obj = calloc(1, sizeof(*event_obj));
1823 if(!event_obj)
1824 return NULL;
1826 event_obj->IHTMLEventObj_iface.lpVtbl = &HTMLEventObjVtbl;
1827 event_obj->IHTMLEventObj2_iface.lpVtbl = &HTMLEventObj2Vtbl;
1828 event_obj->IHTMLEventObj3_iface.lpVtbl = &HTMLEventObj3Vtbl;
1829 event_obj->IHTMLEventObj4_iface.lpVtbl = &HTMLEventObj4Vtbl;
1830 event_obj->IHTMLEventObj5_iface.lpVtbl = &HTMLEventObj5Vtbl;
1831 event_obj->IHTMLEventObj6_iface.lpVtbl = &HTMLEventObj6Vtbl;
1832 event_obj->event = event;
1833 if(event) {
1834 IDOMEvent_AddRef(&event->IDOMEvent_iface);
1835 init_dispatch_with_owner(&event_obj->dispex, &HTMLEventObj_dispex, &event->dispex);
1836 }else {
1837 init_dispatch(&event_obj->dispex, &HTMLEventObj_dispex, script_global,
1838 dispex_compat_mode(&script_global->event_target.dispex));
1840 return event_obj;
1843 HRESULT create_event_obj(DOMEvent *event, HTMLDocumentNode *doc, IHTMLEventObj **ret)
1845 HTMLEventObj *event_obj;
1847 event_obj = alloc_event_obj(event, doc->script_global);
1848 if(!event_obj)
1849 return E_OUTOFMEMORY;
1851 *ret = &event_obj->IHTMLEventObj_iface;
1852 return S_OK;
1855 static inline DOMEvent *impl_from_IDOMEvent(IDOMEvent *iface)
1857 return CONTAINING_RECORD(iface, DOMEvent, IDOMEvent_iface);
1860 static const IDOMEventVtbl DOMEventVtbl;
1862 static inline DOMEvent *unsafe_impl_from_IDOMEvent(IDOMEvent *iface)
1864 return iface && iface->lpVtbl == &DOMEventVtbl ? impl_from_IDOMEvent(iface) : NULL;
1867 DISPEX_IDISPATCH_IMPL(DOMEvent, IDOMEvent, impl_from_IDOMEvent(iface)->dispex)
1869 static HRESULT WINAPI DOMEvent_get_bubbles(IDOMEvent *iface, VARIANT_BOOL *p)
1871 DOMEvent *This = impl_from_IDOMEvent(iface);
1873 TRACE("(%p)->(%p)\n", This, p);
1875 *p = variant_bool(This->bubbles);
1876 return S_OK;
1879 static HRESULT WINAPI DOMEvent_get_cancelable(IDOMEvent *iface, VARIANT_BOOL *p)
1881 DOMEvent *This = impl_from_IDOMEvent(iface);
1883 TRACE("(%p)->(%p)\n", This, p);
1885 *p = variant_bool(This->cancelable);
1886 return S_OK;
1889 static HRESULT WINAPI DOMEvent_get_currentTarget(IDOMEvent *iface, IEventTarget **p)
1891 DOMEvent *This = impl_from_IDOMEvent(iface);
1893 TRACE("(%p)->(%p)\n", This, p);
1895 if(This->current_target)
1896 *p = get_event_target_iface(This->current_target);
1897 else
1898 *p = NULL;
1899 return S_OK;
1902 static HRESULT WINAPI DOMEvent_get_defaultPrevented(IDOMEvent *iface, VARIANT_BOOL *p)
1904 DOMEvent *This = impl_from_IDOMEvent(iface);
1906 TRACE("(%p)->(%p)\n", This, p);
1908 *p = variant_bool(This->prevent_default);
1909 return S_OK;
1912 static HRESULT WINAPI DOMEvent_get_eventPhase(IDOMEvent *iface, USHORT *p)
1914 DOMEvent *This = impl_from_IDOMEvent(iface);
1916 TRACE("(%p)->(%p)\n", This, p);
1918 *p = This->phase;
1919 return S_OK;
1922 static HRESULT WINAPI DOMEvent_get_target(IDOMEvent *iface, IEventTarget **p)
1924 DOMEvent *This = impl_from_IDOMEvent(iface);
1926 TRACE("(%p)->(%p)\n", This, p);
1928 if(This->target)
1929 *p = get_event_target_iface(This->target);
1930 else
1931 *p = NULL;
1932 return S_OK;
1935 static HRESULT WINAPI DOMEvent_get_timeStamp(IDOMEvent *iface, ULONGLONG *p)
1937 DOMEvent *This = impl_from_IDOMEvent(iface);
1939 TRACE("(%p)->(%p)\n", This, p);
1941 *p = This->time_stamp;
1942 return S_OK;
1945 static HRESULT WINAPI DOMEvent_get_type(IDOMEvent *iface, BSTR *p)
1947 DOMEvent *This = impl_from_IDOMEvent(iface);
1949 TRACE("(%p)->(%p)\n", This, p);
1951 if(This->type) {
1952 *p = SysAllocString(This->type);
1953 if(!*p)
1954 return E_OUTOFMEMORY;
1955 }else {
1956 *p = NULL;
1958 return S_OK;
1961 #ifdef __i386__
1962 #define nsIDOMEvent_InitEvent(_this,type,bubbles,cancelable) \
1963 ((void (WINAPI*)(void*,nsIDOMEvent*,const nsAString*,cpp_bool,cpp_bool)) \
1964 &call_thiscall_func)((_this)->lpVtbl->InitEvent,_this,type,bubbles,cancelable)
1966 #endif
1968 static HRESULT WINAPI DOMEvent_initEvent(IDOMEvent *iface, BSTR type, VARIANT_BOOL can_bubble, VARIANT_BOOL cancelable)
1970 DOMEvent *This = impl_from_IDOMEvent(iface);
1971 nsAString nsstr;
1973 TRACE("(%p)->(%s %x %x)\n", This, debugstr_w(type), can_bubble, cancelable);
1975 if(This->target) {
1976 TRACE("called on already dispatched event\n");
1977 return S_OK;
1980 free(This->type);
1981 This->type = wcsdup(type);
1982 if(!This->type)
1983 return E_OUTOFMEMORY;
1984 This->event_id = str_to_eid(type);
1986 This->bubbles = !!can_bubble;
1987 This->cancelable = !!cancelable;
1989 nsAString_InitDepend(&nsstr, type);
1990 nsIDOMEvent_InitEvent(This->nsevent, &nsstr, This->bubbles, This->cancelable);
1991 nsAString_Finish(&nsstr);
1993 return S_OK;
1996 static HRESULT WINAPI DOMEvent_preventDefault(IDOMEvent *iface)
1998 DOMEvent *This = impl_from_IDOMEvent(iface);
2000 TRACE("(%p)\n", This);
2002 if(This->current_target && This->cancelable) {
2003 This->prevent_default = TRUE;
2004 nsIDOMEvent_PreventDefault(This->nsevent);
2006 return S_OK;
2009 static HRESULT WINAPI DOMEvent_stopPropagation(IDOMEvent *iface)
2011 DOMEvent *This = impl_from_IDOMEvent(iface);
2013 TRACE("(%p)\n", This);
2015 This->stop_propagation = TRUE;
2016 nsIDOMEvent_StopPropagation(This->nsevent);
2017 return S_OK;
2020 static HRESULT WINAPI DOMEvent_stopImmediatePropagation(IDOMEvent *iface)
2022 DOMEvent *This = impl_from_IDOMEvent(iface);
2024 TRACE("(%p)\n", This);
2026 This->stop_immediate_propagation = This->stop_propagation = TRUE;
2027 nsIDOMEvent_StopImmediatePropagation(This->nsevent);
2028 return S_OK;
2031 static HRESULT WINAPI DOMEvent_get_isTrusted(IDOMEvent *iface, VARIANT_BOOL *p)
2033 DOMEvent *This = impl_from_IDOMEvent(iface);
2035 TRACE("(%p)->(%p)\n", This, p);
2037 *p = variant_bool(This->trusted);
2038 return S_OK;
2041 static HRESULT WINAPI DOMEvent_put_cancelBubble(IDOMEvent *iface, VARIANT_BOOL v)
2043 DOMEvent *This = impl_from_IDOMEvent(iface);
2044 FIXME("(%p)->(%x)\n", This, v);
2045 return E_NOTIMPL;
2048 static HRESULT WINAPI DOMEvent_get_cancelBubble(IDOMEvent *iface, VARIANT_BOOL *p)
2050 DOMEvent *This = impl_from_IDOMEvent(iface);
2051 FIXME("(%p)->(%p)\n", This, p);
2052 return E_NOTIMPL;
2055 static HRESULT WINAPI DOMEvent_get_srcElement(IDOMEvent *iface, IHTMLElement **p)
2057 DOMEvent *This = impl_from_IDOMEvent(iface);
2059 TRACE("(%p)->(%p)\n", This, p);
2061 if(This->target)
2062 IWineJSDispatchHost_QueryInterface(&This->target->dispex.IWineJSDispatchHost_iface, &IID_IHTMLElement, (void**)p);
2063 else
2064 *p = NULL;
2065 return S_OK;
2068 static const IDOMEventVtbl DOMEventVtbl = {
2069 DOMEvent_QueryInterface,
2070 DOMEvent_AddRef,
2071 DOMEvent_Release,
2072 DOMEvent_GetTypeInfoCount,
2073 DOMEvent_GetTypeInfo,
2074 DOMEvent_GetIDsOfNames,
2075 DOMEvent_Invoke,
2076 DOMEvent_get_bubbles,
2077 DOMEvent_get_cancelable,
2078 DOMEvent_get_currentTarget,
2079 DOMEvent_get_defaultPrevented,
2080 DOMEvent_get_eventPhase,
2081 DOMEvent_get_target,
2082 DOMEvent_get_timeStamp,
2083 DOMEvent_get_type,
2084 DOMEvent_initEvent,
2085 DOMEvent_preventDefault,
2086 DOMEvent_stopPropagation,
2087 DOMEvent_stopImmediatePropagation,
2088 DOMEvent_get_isTrusted,
2089 DOMEvent_put_cancelBubble,
2090 DOMEvent_get_cancelBubble,
2091 DOMEvent_get_srcElement
2094 static inline DOMEvent *DOMEvent_from_DispatchEx(DispatchEx *iface)
2096 return CONTAINING_RECORD(iface, DOMEvent, dispex);
2099 static void *DOMEvent_query_interface(DispatchEx *dispex, REFIID riid)
2101 DOMEvent *This = DOMEvent_from_DispatchEx(dispex);
2103 if(IsEqualGUID(&IID_IDOMEvent, riid))
2104 return &This->IDOMEvent_iface;
2106 return NULL;
2109 static void DOMEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb)
2111 DOMEvent *This = DOMEvent_from_DispatchEx(dispex);
2112 if(This->target)
2113 note_cc_edge((nsISupports*)&This->target->IEventTarget_iface, "target", cb);
2114 if(This->nsevent)
2115 note_cc_edge((nsISupports*)This->nsevent, "nsevent", cb);
2118 static void DOMEvent_unlink(DispatchEx *dispex)
2120 DOMEvent *This = DOMEvent_from_DispatchEx(dispex);
2121 if(This->target) {
2122 EventTarget *target = This->target;
2123 This->target = NULL;
2124 IEventTarget_Release(&target->IEventTarget_iface);
2126 unlink_ref(&This->nsevent);
2129 static void DOMEvent_destructor(DispatchEx *dispex)
2131 DOMEvent *This = DOMEvent_from_DispatchEx(dispex);
2132 free(This->type);
2133 free(This);
2136 static inline DOMUIEvent *impl_from_IDOMUIEvent(IDOMUIEvent *iface)
2138 return CONTAINING_RECORD(iface, DOMUIEvent, IDOMUIEvent_iface);
2141 DISPEX_IDISPATCH_IMPL(DOMUIEvent, IDOMUIEvent, impl_from_IDOMUIEvent(iface)->event.dispex)
2143 static HRESULT WINAPI DOMUIEvent_get_view(IDOMUIEvent *iface, IHTMLWindow2 **p)
2145 DOMUIEvent *This = impl_from_IDOMUIEvent(iface);
2146 mozIDOMWindowProxy *moz_window;
2147 HTMLOuterWindow *view = NULL;
2148 nsresult nsres;
2150 TRACE("(%p)->(%p)\n", This, p);
2152 nsres = nsIDOMUIEvent_GetView(This->nsevent, &moz_window);
2153 if(NS_FAILED(nsres))
2154 return E_FAIL;
2156 if(moz_window) {
2157 view = mozwindow_to_window(moz_window);
2158 mozIDOMWindowProxy_Release(moz_window);
2160 if(view)
2161 IHTMLWindow2_AddRef((*p = &view->base.IHTMLWindow2_iface));
2162 else
2163 *p = NULL;
2164 return S_OK;
2167 static HRESULT WINAPI DOMUIEvent_get_detail(IDOMUIEvent *iface, LONG *p)
2169 DOMUIEvent *This = impl_from_IDOMUIEvent(iface);
2170 LONG detail;
2171 nsresult nsres;
2173 TRACE("(%p)->(%p)\n", This, p);
2175 nsres = nsIDOMUIEvent_GetDetail(This->nsevent, &detail);
2176 if(NS_FAILED(nsres))
2177 return E_FAIL;
2179 *p = detail;
2180 return S_OK;
2183 static HRESULT WINAPI DOMUIEvent_initUIEvent(IDOMUIEvent *iface, BSTR type, VARIANT_BOOL can_bubble,
2184 VARIANT_BOOL cancelable, IHTMLWindow2 *view, LONG detail)
2186 DOMUIEvent *This = impl_from_IDOMUIEvent(iface);
2187 nsAString type_str;
2188 nsresult nsres;
2189 HRESULT hres;
2191 TRACE("(%p)->(%s %x %x %p %lx)\n", This, debugstr_w(type), can_bubble, cancelable, view, detail);
2193 if(This->event.target) {
2194 TRACE("called on already dispatched event\n");
2195 return S_OK;
2198 if(view)
2199 FIXME("view argument is not supported\n");
2201 hres = IDOMEvent_initEvent(&This->event.IDOMEvent_iface, type, can_bubble, cancelable);
2202 if(FAILED(hres))
2203 return hres;
2205 nsAString_InitDepend(&type_str, type);
2206 nsres = nsIDOMUIEvent_InitUIEvent(This->nsevent, &type_str, !!can_bubble, !!cancelable,
2207 NULL /* FIXME */, detail);
2208 nsAString_Finish(&type_str);
2209 if(NS_FAILED(nsres)) {
2210 FIXME("InitUIEvent failed: %08lx\n", nsres);
2211 return E_FAIL;
2214 return S_OK;
2217 static const IDOMUIEventVtbl DOMUIEventVtbl = {
2218 DOMUIEvent_QueryInterface,
2219 DOMUIEvent_AddRef,
2220 DOMUIEvent_Release,
2221 DOMUIEvent_GetTypeInfoCount,
2222 DOMUIEvent_GetTypeInfo,
2223 DOMUIEvent_GetIDsOfNames,
2224 DOMUIEvent_Invoke,
2225 DOMUIEvent_get_view,
2226 DOMUIEvent_get_detail,
2227 DOMUIEvent_initUIEvent
2230 static void *DOMUIEvent_query_interface(DispatchEx *dispex, REFIID riid)
2232 DOMUIEvent *This = DOMUIEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
2234 if(IsEqualGUID(&IID_IDOMUIEvent, riid))
2235 return &This->IDOMUIEvent_iface;
2236 return DOMEvent_query_interface(&This->event.dispex, riid);
2239 static void DOMUIEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb)
2241 DOMUIEvent *This = DOMUIEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
2242 DOMEvent_traverse(&This->event.dispex, cb);
2243 if(This->nsevent)
2244 note_cc_edge((nsISupports*)This->nsevent, "UIEvent.nsevent", cb);
2247 static void DOMUIEvent_unlink(DispatchEx *dispex)
2249 DOMUIEvent *This = DOMUIEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
2250 DOMEvent_unlink(&This->event.dispex);
2251 unlink_ref(&This->nsevent);
2254 typedef struct {
2255 DOMUIEvent ui_event;
2256 IDOMMouseEvent IDOMMouseEvent_iface;
2257 nsIDOMMouseEvent *nsevent;
2258 } DOMMouseEvent;
2260 static inline DOMMouseEvent *impl_from_IDOMMouseEvent(IDOMMouseEvent *iface)
2262 return CONTAINING_RECORD(iface, DOMMouseEvent, IDOMMouseEvent_iface);
2265 DISPEX_IDISPATCH_IMPL(DOMMouseEvent, IDOMMouseEvent, impl_from_IDOMMouseEvent(iface)->ui_event.event.dispex)
2267 static HRESULT WINAPI DOMMouseEvent_get_screenX(IDOMMouseEvent *iface, LONG *p)
2269 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2270 LONG screen_x;
2271 nsresult nsres;
2273 TRACE("(%p)->(%p)\n", This, p);
2275 nsres = nsIDOMMouseEvent_GetScreenX(This->nsevent, &screen_x);
2276 if(NS_FAILED(nsres))
2277 return E_FAIL;
2279 *p = screen_x;
2280 return S_OK;
2283 static HRESULT WINAPI DOMMouseEvent_get_screenY(IDOMMouseEvent *iface, LONG *p)
2285 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2286 LONG screen_y;
2287 nsresult nsres;
2289 TRACE("(%p)->(%p)\n", This, p);
2291 nsres = nsIDOMMouseEvent_GetScreenY(This->nsevent, &screen_y);
2292 if(NS_FAILED(nsres))
2293 return E_FAIL;
2295 *p = screen_y;
2296 return S_OK;
2299 static HRESULT WINAPI DOMMouseEvent_get_clientX(IDOMMouseEvent *iface, LONG *p)
2301 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2302 LONG client_x;
2303 nsresult nsres;
2305 TRACE("(%p)->(%p)\n", This, p);
2307 nsres = nsIDOMMouseEvent_GetClientX(This->nsevent, &client_x);
2308 if(NS_FAILED(nsres))
2309 return E_FAIL;
2311 *p = client_x;
2312 return S_OK;
2315 static HRESULT WINAPI DOMMouseEvent_get_clientY(IDOMMouseEvent *iface, LONG *p)
2317 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2318 LONG client_y;
2319 nsresult nsres;
2321 TRACE("(%p)->(%p)\n", This, p);
2323 nsres = nsIDOMMouseEvent_GetClientY(This->nsevent, &client_y);
2324 if(NS_FAILED(nsres))
2325 return E_FAIL;
2327 *p = client_y;
2328 return S_OK;
2331 static HRESULT WINAPI DOMMouseEvent_get_ctrlKey(IDOMMouseEvent *iface, VARIANT_BOOL *p)
2333 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2334 cpp_bool r;
2335 nsresult nsres;
2337 TRACE("(%p)->(%p)\n", This, p);
2339 nsres = nsIDOMMouseEvent_GetCtrlKey(This->nsevent, &r);
2340 if(NS_FAILED(nsres))
2341 return E_FAIL;
2343 *p = variant_bool(r);
2344 return S_OK;
2347 static HRESULT WINAPI DOMMouseEvent_get_shiftKey(IDOMMouseEvent *iface, VARIANT_BOOL *p)
2349 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2350 cpp_bool r;
2351 nsresult nsres;
2353 TRACE("(%p)->(%p)\n", This, p);
2355 nsres = nsIDOMMouseEvent_GetShiftKey(This->nsevent, &r);
2356 if(NS_FAILED(nsres))
2357 return E_FAIL;
2359 *p = variant_bool(r);
2360 return S_OK;
2363 static HRESULT WINAPI DOMMouseEvent_get_altKey(IDOMMouseEvent *iface, VARIANT_BOOL *p)
2365 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2366 cpp_bool r;
2367 nsresult nsres;
2369 TRACE("(%p)->(%p)\n", This, p);
2371 nsres = nsIDOMMouseEvent_GetAltKey(This->nsevent, &r);
2372 if(NS_FAILED(nsres))
2373 return E_FAIL;
2375 *p = variant_bool(r);
2376 return S_OK;
2379 static HRESULT WINAPI DOMMouseEvent_get_metaKey(IDOMMouseEvent *iface, VARIANT_BOOL *p)
2381 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2382 cpp_bool r;
2383 nsresult nsres;
2385 TRACE("(%p)->(%p)\n", This, p);
2387 nsres = nsIDOMMouseEvent_GetMetaKey(This->nsevent, &r);
2388 if(NS_FAILED(nsres))
2389 return E_FAIL;
2391 *p = variant_bool(r);
2392 return S_OK;
2395 static HRESULT WINAPI DOMMouseEvent_get_button(IDOMMouseEvent *iface, USHORT *p)
2397 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2398 INT16 r;
2399 nsresult nsres;
2401 TRACE("(%p)->(%p)\n", This, p);
2403 nsres = nsIDOMMouseEvent_GetButton(This->nsevent, &r);
2404 if(NS_FAILED(nsres))
2405 return E_FAIL;
2407 *p = r;
2408 return S_OK;
2411 static HRESULT WINAPI DOMMouseEvent_get_relatedTarget(IDOMMouseEvent *iface, IEventTarget **p)
2413 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2414 nsIDOMEventTarget *related_target;
2415 nsIDOMNode *target_node;
2416 HTMLDOMNode *node;
2417 HRESULT hres;
2418 nsresult nsres;
2420 TRACE("(%p)->(%p)\n", This, p);
2422 nsres = nsIDOMMouseEvent_GetRelatedTarget(This->nsevent, &related_target);
2423 if(NS_FAILED(nsres))
2424 return E_FAIL;
2426 if(!related_target) {
2427 *p = NULL;
2428 return S_OK;
2431 nsres = nsIDOMEventTarget_QueryInterface(related_target, &IID_nsIDOMNode, (void**)&target_node);
2432 nsIDOMEventTarget_Release(related_target);
2433 if(NS_FAILED(nsres)) {
2434 FIXME("Only node targets supported\n");
2435 return E_NOTIMPL;
2438 hres = get_node(target_node, TRUE, &node);
2439 nsIDOMNode_Release(target_node);
2440 if(FAILED(hres))
2441 return hres;
2443 *p = &node->event_target.IEventTarget_iface;
2444 return S_OK;
2447 static HRESULT WINAPI DOMMouseEvent_initMouseEvent(IDOMMouseEvent *iface, BSTR type,
2448 VARIANT_BOOL can_bubble, VARIANT_BOOL cancelable, IHTMLWindow2 *view, LONG detail,
2449 LONG screen_x, LONG screen_y, LONG client_x, LONG client_y, VARIANT_BOOL ctrl_key,
2450 VARIANT_BOOL alt_key, VARIANT_BOOL shift_key, VARIANT_BOOL meta_key, USHORT button,
2451 IEventTarget *related_target)
2453 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2454 nsIDOMEventTarget *nstarget = NULL;
2455 nsAString type_str;
2456 nsresult nsres;
2457 HRESULT hres;
2459 TRACE("(%p)->(%s %x %x %p %ld %ld %ld %ld %ld %x %x %x %x %u %p)\n", This, debugstr_w(type),
2460 can_bubble, cancelable, view, detail, screen_x, screen_y, client_x, client_y,
2461 ctrl_key, alt_key, shift_key, meta_key, button, related_target);
2463 if(This->ui_event.event.target) {
2464 TRACE("called on already dispatched event\n");
2465 return S_OK;
2468 if(view)
2469 FIXME("view argument is not supported\n");
2471 if(related_target) {
2472 hres = get_gecko_target(related_target, &nstarget);
2473 if(FAILED(hres))
2474 return hres;
2477 hres = IDOMEvent_initEvent(&This->ui_event.event.IDOMEvent_iface, type, can_bubble, cancelable);
2478 if(SUCCEEDED(hres)) {
2479 nsAString_InitDepend(&type_str, type);
2480 nsres = nsIDOMMouseEvent_InitMouseEvent(This->nsevent, &type_str, can_bubble, cancelable,
2481 NULL /* FIXME */, detail, screen_x, screen_y,
2482 client_x, client_y, !!ctrl_key, !!alt_key, !!shift_key,
2483 !!meta_key, button, nstarget);
2484 nsAString_Finish(&type_str);
2485 if(NS_FAILED(nsres)) {
2486 FIXME("InitMouseEvent failed: %08lx\n", nsres);
2487 return E_FAIL;
2491 if(nstarget)
2492 nsIDOMEventTarget_Release(nstarget);
2493 return S_OK;
2496 static HRESULT WINAPI DOMMouseEvent_getModifierState(IDOMMouseEvent *iface, BSTR key,
2497 VARIANT_BOOL *activated)
2499 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2500 FIXME("(%p)->(%s %p)\n", This, debugstr_w(key), activated);
2501 return E_NOTIMPL;
2504 static HRESULT WINAPI DOMMouseEvent_get_buttons(IDOMMouseEvent *iface, USHORT *p)
2506 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2507 UINT16 r;
2508 nsresult nsres;
2510 TRACE("(%p)->(%p)\n", This, p);
2512 nsres = nsIDOMMouseEvent_GetButtons(This->nsevent, &r);
2513 if(NS_FAILED(nsres))
2514 return E_FAIL;
2516 *p = r;
2517 return S_OK;
2520 static HRESULT WINAPI DOMMouseEvent_get_fromElement(IDOMMouseEvent *iface, IHTMLElement **p)
2522 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2523 eventid_t event_id = This->ui_event.event.event_id;
2524 IEventTarget *related_target = NULL;
2525 HRESULT hres = S_OK;
2527 TRACE("(%p)->(%p)\n", This, p);
2529 if(event_info[event_id].flags & EVENT_MOUSE_FROM_RELATED)
2530 hres = IDOMMouseEvent_get_relatedTarget(&This->IDOMMouseEvent_iface, &related_target);
2531 else if(event_info[event_id].flags & EVENT_MOUSE_TO_RELATED)
2532 hres = IDOMEvent_get_target(&This->ui_event.event.IDOMEvent_iface, &related_target);
2533 if(FAILED(hres))
2534 return hres;
2536 if(!related_target) {
2537 *p = NULL;
2538 return S_OK;
2541 IEventTarget_QueryInterface(related_target, &IID_IHTMLElement, (void**)p);
2542 return S_OK;
2545 static HRESULT WINAPI DOMMouseEvent_get_toElement(IDOMMouseEvent *iface, IHTMLElement **p)
2547 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2548 eventid_t event_id = This->ui_event.event.event_id;
2549 IEventTarget *related_target = NULL;
2550 HRESULT hres = S_OK;
2552 TRACE("(%p)->(%p)\n", This, p);
2554 if(event_info[event_id].flags & EVENT_MOUSE_TO_RELATED)
2555 hres = IDOMMouseEvent_get_relatedTarget(&This->IDOMMouseEvent_iface, &related_target);
2556 else if(event_info[event_id].flags & EVENT_MOUSE_FROM_RELATED)
2557 hres = IDOMEvent_get_target(&This->ui_event.event.IDOMEvent_iface, &related_target);
2558 if(FAILED(hres))
2559 return hres;
2561 if(!related_target) {
2562 *p = NULL;
2563 return S_OK;
2566 IEventTarget_QueryInterface(related_target, &IID_IHTMLElement, (void**)p);
2567 return S_OK;
2570 static HRESULT WINAPI DOMMouseEvent_get_x(IDOMMouseEvent *iface, LONG *p)
2572 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2573 FIXME("(%p)->(%p)\n", This, p);
2574 return E_NOTIMPL;
2577 static HRESULT WINAPI DOMMouseEvent_get_y(IDOMMouseEvent *iface, LONG *p)
2579 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2580 FIXME("(%p)->(%p)\n", This, p);
2581 return E_NOTIMPL;
2584 static HRESULT WINAPI DOMMouseEvent_get_offsetX(IDOMMouseEvent *iface, LONG *p)
2586 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2588 FIXME("(%p)->(%p) returning 0\n", This, p);
2590 *p = 0;
2591 return S_OK;
2594 static HRESULT WINAPI DOMMouseEvent_get_offsetY(IDOMMouseEvent *iface, LONG *p)
2596 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2598 FIXME("(%p)->(%p) returning 0\n", This, p);
2600 *p = 0;
2601 return S_OK;
2604 static HRESULT WINAPI DOMMouseEvent_get_pageX(IDOMMouseEvent *iface, LONG *p)
2606 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2607 LONG r;
2608 nsresult nsres;
2610 TRACE("(%p)->(%p)\n", This, p);
2612 nsres = nsIDOMMouseEvent_GetPageX(This->nsevent, &r);
2613 if(NS_FAILED(nsres))
2614 return E_FAIL;
2616 *p = r;
2617 return S_OK;
2620 static HRESULT WINAPI DOMMouseEvent_get_pageY(IDOMMouseEvent *iface, LONG *p)
2622 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2623 LONG r;
2624 nsresult nsres;
2626 TRACE("(%p)->(%p)\n", This, p);
2628 nsres = nsIDOMMouseEvent_GetPageY(This->nsevent, &r);
2629 if(NS_FAILED(nsres))
2630 return E_FAIL;
2632 *p = r;
2633 return S_OK;
2636 static HRESULT WINAPI DOMMouseEvent_get_layerX(IDOMMouseEvent *iface, LONG *p)
2638 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2639 nsresult nsres;
2640 LONG r;
2642 TRACE("(%p)->(%p)\n", This, p);
2644 nsres = nsIDOMMouseEvent_GetLayerX(This->nsevent, &r);
2645 if(NS_FAILED(nsres))
2646 return E_FAIL;
2648 *p = r;
2649 return S_OK;
2652 static HRESULT WINAPI DOMMouseEvent_get_layerY(IDOMMouseEvent *iface, LONG *p)
2654 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2655 nsresult nsres;
2656 LONG r;
2658 TRACE("(%p)->(%p)\n", This, p);
2660 nsres = nsIDOMMouseEvent_GetLayerY(This->nsevent, &r);
2661 if(NS_FAILED(nsres))
2662 return E_FAIL;
2664 *p = r;
2665 return S_OK;
2668 static HRESULT WINAPI DOMMouseEvent_get_which(IDOMMouseEvent *iface, USHORT *p)
2670 DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
2671 UINT32 r;
2672 nsresult nsres;
2674 TRACE("(%p)->(%p)\n", This, p);
2676 nsres = nsIDOMMouseEvent_GetWhich(This->nsevent, &r);
2677 if(NS_FAILED(nsres))
2678 return E_FAIL;
2680 *p = r;
2681 return S_OK;
2684 static const IDOMMouseEventVtbl DOMMouseEventVtbl = {
2685 DOMMouseEvent_QueryInterface,
2686 DOMMouseEvent_AddRef,
2687 DOMMouseEvent_Release,
2688 DOMMouseEvent_GetTypeInfoCount,
2689 DOMMouseEvent_GetTypeInfo,
2690 DOMMouseEvent_GetIDsOfNames,
2691 DOMMouseEvent_Invoke,
2692 DOMMouseEvent_get_screenX,
2693 DOMMouseEvent_get_screenY,
2694 DOMMouseEvent_get_clientX,
2695 DOMMouseEvent_get_clientY,
2696 DOMMouseEvent_get_ctrlKey,
2697 DOMMouseEvent_get_shiftKey,
2698 DOMMouseEvent_get_altKey,
2699 DOMMouseEvent_get_metaKey,
2700 DOMMouseEvent_get_button,
2701 DOMMouseEvent_get_relatedTarget,
2702 DOMMouseEvent_initMouseEvent,
2703 DOMMouseEvent_getModifierState,
2704 DOMMouseEvent_get_buttons,
2705 DOMMouseEvent_get_fromElement,
2706 DOMMouseEvent_get_toElement,
2707 DOMMouseEvent_get_x,
2708 DOMMouseEvent_get_y,
2709 DOMMouseEvent_get_offsetX,
2710 DOMMouseEvent_get_offsetY,
2711 DOMMouseEvent_get_pageX,
2712 DOMMouseEvent_get_pageY,
2713 DOMMouseEvent_get_layerX,
2714 DOMMouseEvent_get_layerY,
2715 DOMMouseEvent_get_which
2718 static DOMMouseEvent *DOMMouseEvent_from_DOMEvent(DOMEvent *event)
2720 return CONTAINING_RECORD(event, DOMMouseEvent, ui_event.event);
2723 static void *DOMMouseEvent_query_interface(DispatchEx *dispex, REFIID riid)
2725 DOMMouseEvent *This = DOMMouseEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
2727 if(IsEqualGUID(&IID_IDOMMouseEvent, riid))
2728 return &This->IDOMMouseEvent_iface;
2729 if(IsEqualGUID(&IID_IDOMUIEvent, riid))
2730 return &This->ui_event.IDOMUIEvent_iface;
2731 return DOMEvent_query_interface(&This->ui_event.event.dispex, riid);
2734 static void DOMMouseEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb)
2736 DOMMouseEvent *This = DOMMouseEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
2737 DOMUIEvent_traverse(&This->ui_event.event.dispex, cb);
2738 if(This->nsevent)
2739 note_cc_edge((nsISupports*)This->nsevent, "MouseEvent.nsevent", cb);
2742 static void DOMMouseEvent_unlink(DispatchEx *dispex)
2744 DOMMouseEvent *This = DOMMouseEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
2745 DOMUIEvent_unlink(&This->ui_event.event.dispex);
2746 unlink_ref(&This->nsevent);
2749 typedef struct {
2750 DOMUIEvent ui_event;
2751 IDOMKeyboardEvent IDOMKeyboardEvent_iface;
2752 nsIDOMKeyEvent *nsevent;
2753 } DOMKeyboardEvent;
2755 static inline DOMKeyboardEvent *impl_from_IDOMKeyboardEvent(IDOMKeyboardEvent *iface)
2757 return CONTAINING_RECORD(iface, DOMKeyboardEvent, IDOMKeyboardEvent_iface);
2760 DISPEX_IDISPATCH_IMPL(DOMKeyboardEvent, IDOMKeyboardEvent,
2761 impl_from_IDOMKeyboardEvent(iface)->ui_event.event.dispex)
2763 static HRESULT WINAPI DOMKeyboardEvent_get_key(IDOMKeyboardEvent *iface, BSTR *p)
2765 DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface);
2766 nsAString key_str;
2767 nsresult nsres;
2769 TRACE("(%p)->(%p)\n", This, p);
2772 nsAString_Init(&key_str, NULL);
2773 nsres = nsIDOMKeyEvent_GetKey(This->nsevent, &key_str);
2774 return return_nsstr(nsres, &key_str, p);
2777 static HRESULT WINAPI DOMKeyboardEvent_get_location(IDOMKeyboardEvent *iface, ULONG *p)
2779 DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface);
2780 UINT32 r;
2781 nsresult nsres;
2783 TRACE("(%p)->(%p)\n", This, p);
2785 nsres = nsIDOMKeyEvent_GetLocation(This->nsevent, &r);
2786 if(NS_FAILED(nsres))
2787 return E_FAIL;
2789 *p = r;
2790 return S_OK;
2793 static HRESULT WINAPI DOMKeyboardEvent_get_ctrlKey(IDOMKeyboardEvent *iface, VARIANT_BOOL *p)
2795 DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface);
2796 cpp_bool r;
2797 nsresult nsres;
2799 TRACE("(%p)->(%p)\n", This, p);
2801 nsres = nsIDOMKeyEvent_GetCtrlKey(This->nsevent, &r);
2802 if(NS_FAILED(nsres))
2803 return E_FAIL;
2805 *p = variant_bool(r);
2806 return S_OK;
2809 static HRESULT WINAPI DOMKeyboardEvent_get_shiftKey(IDOMKeyboardEvent *iface, VARIANT_BOOL *p)
2811 DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface);
2812 cpp_bool r;
2813 nsresult nsres;
2815 TRACE("(%p)->(%p)\n", This, p);
2817 nsres = nsIDOMKeyEvent_GetShiftKey(This->nsevent, &r);
2818 if(NS_FAILED(nsres))
2819 return E_FAIL;
2821 *p = variant_bool(r);
2822 return S_OK;
2825 static HRESULT WINAPI DOMKeyboardEvent_get_altKey(IDOMKeyboardEvent *iface, VARIANT_BOOL *p)
2827 DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface);
2828 cpp_bool r;
2829 nsresult nsres;
2831 TRACE("(%p)->(%p)\n", This, p);
2833 nsres = nsIDOMKeyEvent_GetAltKey(This->nsevent, &r);
2834 if(NS_FAILED(nsres))
2835 return E_FAIL;
2837 *p = variant_bool(r);
2838 return S_OK;
2841 static HRESULT WINAPI DOMKeyboardEvent_get_metaKey(IDOMKeyboardEvent *iface, VARIANT_BOOL *p)
2843 DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface);
2844 cpp_bool r;
2845 nsresult nsres;
2847 TRACE("(%p)->(%p)\n", This, p);
2849 nsres = nsIDOMKeyEvent_GetMetaKey(This->nsevent, &r);
2850 if(NS_FAILED(nsres))
2851 return E_FAIL;
2853 *p = variant_bool(r);
2854 return S_OK;
2857 static HRESULT WINAPI DOMKeyboardEvent_get_repeat(IDOMKeyboardEvent *iface, VARIANT_BOOL *p)
2859 DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface);
2860 cpp_bool r;
2861 nsresult nsres;
2863 TRACE("(%p)->(%p)\n", This, p);
2865 nsres = nsIDOMKeyEvent_GetRepeat(This->nsevent, &r);
2866 if(NS_FAILED(nsres))
2867 return E_FAIL;
2869 *p = variant_bool(r);
2870 return S_OK;
2873 static HRESULT WINAPI DOMKeyboardEvent_getModifierState(IDOMKeyboardEvent *iface, BSTR key,
2874 VARIANT_BOOL *state)
2876 DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface);
2877 FIXME("(%p)->(%s %p)\n", This, debugstr_w(key), state);
2878 return E_NOTIMPL;
2881 static HRESULT WINAPI DOMKeyboardEvent_initKeyboardEvent(IDOMKeyboardEvent *iface, BSTR type,
2882 VARIANT_BOOL can_bubble, VARIANT_BOOL cancelable, IHTMLWindow2 *view, BSTR key,
2883 ULONG location, BSTR modifiers_list, VARIANT_BOOL repeat, BSTR locale)
2885 DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface);
2886 FIXME("(%p)->(%s %x %x %p %s %lu %s %x %s)\n", This, debugstr_w(type), can_bubble,
2887 cancelable, view, debugstr_w(key), location, debugstr_w(modifiers_list),
2888 repeat, debugstr_w(locale));
2889 return E_NOTIMPL;
2892 static HRESULT WINAPI DOMKeyboardEvent_get_keyCode(IDOMKeyboardEvent *iface, LONG *p)
2894 DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface);
2895 UINT32 r;
2896 nsresult nsres;
2898 TRACE("(%p)->(%p)\n", This, p);
2900 nsres = nsIDOMKeyEvent_GetKeyCode(This->nsevent, &r);
2901 if(NS_FAILED(nsres))
2902 return E_FAIL;
2904 *p = r;
2905 return S_OK;
2908 static HRESULT WINAPI DOMKeyboardEvent_get_charCode(IDOMKeyboardEvent *iface, LONG *p)
2910 DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface);
2911 UINT32 r;
2912 nsresult nsres;
2914 TRACE("(%p)->(%p)\n", This, p);
2916 nsres = nsIDOMKeyEvent_GetKeyCode(This->nsevent, &r);
2917 if(NS_FAILED(nsres))
2918 return E_FAIL;
2920 *p = r;
2921 return S_OK;
2924 static HRESULT WINAPI DOMKeyboardEvent_get_which(IDOMKeyboardEvent *iface, LONG *p)
2926 DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface);
2927 UINT32 r;
2928 nsresult nsres;
2930 TRACE("(%p)->(%p)\n", This, p);
2932 nsres = nsIDOMKeyEvent_GetWhich(This->nsevent, &r);
2933 if(NS_FAILED(nsres))
2934 return E_FAIL;
2936 *p = r;
2937 return S_OK;
2940 static HRESULT WINAPI DOMKeyboardEvent_get_char(IDOMKeyboardEvent *iface, VARIANT *p)
2942 DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface);
2943 FIXME("(%p)->(%p)\n", This, p);
2944 return E_NOTIMPL;
2947 static HRESULT WINAPI DOMKeyboardEvent_get_locale(IDOMKeyboardEvent *iface, BSTR *p)
2949 DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface);
2951 FIXME("(%p)->(%p) semi-stub\n", This, p);
2953 *p = SysAllocString(L"");
2954 return *p ? S_OK : E_OUTOFMEMORY;
2957 static const IDOMKeyboardEventVtbl DOMKeyboardEventVtbl = {
2958 DOMKeyboardEvent_QueryInterface,
2959 DOMKeyboardEvent_AddRef,
2960 DOMKeyboardEvent_Release,
2961 DOMKeyboardEvent_GetTypeInfoCount,
2962 DOMKeyboardEvent_GetTypeInfo,
2963 DOMKeyboardEvent_GetIDsOfNames,
2964 DOMKeyboardEvent_Invoke,
2965 DOMKeyboardEvent_get_key,
2966 DOMKeyboardEvent_get_location,
2967 DOMKeyboardEvent_get_ctrlKey,
2968 DOMKeyboardEvent_get_shiftKey,
2969 DOMKeyboardEvent_get_altKey,
2970 DOMKeyboardEvent_get_metaKey,
2971 DOMKeyboardEvent_get_repeat,
2972 DOMKeyboardEvent_getModifierState,
2973 DOMKeyboardEvent_initKeyboardEvent,
2974 DOMKeyboardEvent_get_keyCode,
2975 DOMKeyboardEvent_get_charCode,
2976 DOMKeyboardEvent_get_which,
2977 DOMKeyboardEvent_get_char,
2978 DOMKeyboardEvent_get_locale
2981 static DOMKeyboardEvent *DOMKeyboardEvent_from_DOMEvent(DOMEvent *event)
2983 return CONTAINING_RECORD(event, DOMKeyboardEvent, ui_event.event);
2986 static void *DOMKeyboardEvent_query_interface(DispatchEx *dispex, REFIID riid)
2988 DOMKeyboardEvent *This = DOMKeyboardEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
2990 if(IsEqualGUID(&IID_IDOMKeyboardEvent, riid))
2991 return &This->IDOMKeyboardEvent_iface;
2992 if(IsEqualGUID(&IID_IDOMUIEvent, riid))
2993 return &This->ui_event.IDOMUIEvent_iface;
2994 return DOMEvent_query_interface(&This->ui_event.event.dispex, riid);
2997 static void DOMKeyboardEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb)
2999 DOMKeyboardEvent *This = DOMKeyboardEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
3000 DOMUIEvent_traverse(&This->ui_event.event.dispex, cb);
3001 if(This->nsevent)
3002 note_cc_edge((nsISupports*)This->nsevent, "KeyboardEvent.nsevent", cb);
3005 static void DOMKeyboardEvent_unlink(DispatchEx *dispex)
3007 DOMKeyboardEvent *This = DOMKeyboardEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
3008 DOMUIEvent_unlink(&This->ui_event.event.dispex);
3009 unlink_ref(&This->nsevent);
3012 typedef struct {
3013 DOMEvent event;
3014 IWinePageTransitionEvent IWinePageTransitionEvent_iface;
3015 } DOMPageTransitionEvent;
3017 static inline DOMPageTransitionEvent *impl_from_IWinePageTransitionEvent(IWinePageTransitionEvent *iface)
3019 return CONTAINING_RECORD(iface, DOMPageTransitionEvent, IWinePageTransitionEvent_iface);
3022 DISPEX_IDISPATCH_IMPL(DOMPageTransitionEvent, IWinePageTransitionEvent,
3023 impl_from_IWinePageTransitionEvent(iface)->event.dispex)
3025 static HRESULT WINAPI DOMPageTransitionEvent_get_persisted(IWinePageTransitionEvent *iface, VARIANT_BOOL *p)
3027 DOMPageTransitionEvent *This = impl_from_IWinePageTransitionEvent(iface);
3029 FIXME("(%p)->(%p): always returning FALSE\n", This, p);
3031 *p = VARIANT_FALSE;
3032 return S_OK;
3035 static const IWinePageTransitionEventVtbl DOMPageTransitionEventVtbl = {
3036 DOMPageTransitionEvent_QueryInterface,
3037 DOMPageTransitionEvent_AddRef,
3038 DOMPageTransitionEvent_Release,
3039 DOMPageTransitionEvent_GetTypeInfoCount,
3040 DOMPageTransitionEvent_GetTypeInfo,
3041 DOMPageTransitionEvent_GetIDsOfNames,
3042 DOMPageTransitionEvent_Invoke,
3043 DOMPageTransitionEvent_get_persisted
3046 static DOMPageTransitionEvent *DOMPageTransitionEvent_from_DOMEvent(DOMEvent *event)
3048 return CONTAINING_RECORD(event, DOMPageTransitionEvent, event);
3051 static void *DOMPageTransitionEvent_query_interface(DispatchEx *dispex, REFIID riid)
3053 DOMPageTransitionEvent *page_transition_event = DOMPageTransitionEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
3055 if(IsEqualGUID(&IID_IWinePageTransitionEvent, riid))
3056 return &page_transition_event->IWinePageTransitionEvent_iface;
3057 return DOMEvent_query_interface(&page_transition_event->event.dispex, riid);
3060 typedef struct {
3061 DOMEvent event;
3062 IDOMCustomEvent IDOMCustomEvent_iface;
3063 VARIANT detail;
3064 } DOMCustomEvent;
3066 static inline DOMCustomEvent *impl_from_IDOMCustomEvent(IDOMCustomEvent *iface)
3068 return CONTAINING_RECORD(iface, DOMCustomEvent, IDOMCustomEvent_iface);
3071 DISPEX_IDISPATCH_IMPL(DOMCustomEvent, IDOMCustomEvent, impl_from_IDOMCustomEvent(iface)->event.dispex)
3073 static HRESULT WINAPI DOMCustomEvent_get_detail(IDOMCustomEvent *iface, VARIANT *p)
3075 DOMCustomEvent *This = impl_from_IDOMCustomEvent(iface);
3077 TRACE("(%p)->(%p)\n", This, p);
3079 V_VT(p) = VT_EMPTY;
3080 return VariantCopy(p, &This->detail);
3083 static HRESULT WINAPI DOMCustomEvent_initCustomEvent(IDOMCustomEvent *iface, BSTR type, VARIANT_BOOL can_bubble,
3084 VARIANT_BOOL cancelable, VARIANT *detail)
3086 DOMCustomEvent *This = impl_from_IDOMCustomEvent(iface);
3087 HRESULT hres;
3089 TRACE("(%p)->(%s %x %x %s)\n", This, debugstr_w(type), can_bubble, cancelable, debugstr_variant(detail));
3091 hres = IDOMEvent_initEvent(&This->event.IDOMEvent_iface, type, can_bubble, cancelable);
3092 if(FAILED(hres))
3093 return hres;
3095 return VariantCopy(&This->detail, detail);
3098 static const IDOMCustomEventVtbl DOMCustomEventVtbl = {
3099 DOMCustomEvent_QueryInterface,
3100 DOMCustomEvent_AddRef,
3101 DOMCustomEvent_Release,
3102 DOMCustomEvent_GetTypeInfoCount,
3103 DOMCustomEvent_GetTypeInfo,
3104 DOMCustomEvent_GetIDsOfNames,
3105 DOMCustomEvent_Invoke,
3106 DOMCustomEvent_get_detail,
3107 DOMCustomEvent_initCustomEvent
3110 static DOMCustomEvent *DOMCustomEvent_from_DOMEvent(DOMEvent *event)
3112 return CONTAINING_RECORD(event, DOMCustomEvent, event);
3115 static void *DOMCustomEvent_query_interface(DispatchEx *dispex, REFIID riid)
3117 DOMCustomEvent *custom_event = DOMCustomEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
3119 if(IsEqualGUID(&IID_IDOMCustomEvent, riid))
3120 return &custom_event->IDOMCustomEvent_iface;
3121 return DOMEvent_query_interface(&custom_event->event.dispex, riid);
3124 static void DOMCustomEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb)
3126 DOMCustomEvent *custom_event = DOMCustomEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
3127 DOMEvent_traverse(&custom_event->event.dispex, cb);
3128 traverse_variant(&custom_event->detail, "detail", cb);
3131 static void DOMCustomEvent_unlink(DispatchEx *dispex)
3133 DOMCustomEvent *custom_event = DOMCustomEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
3134 DOMEvent_unlink(&custom_event->event.dispex);
3135 unlink_variant(&custom_event->detail);
3138 static void DOMCustomEvent_destructor(DispatchEx *dispex)
3140 DOMCustomEvent *custom_event = DOMCustomEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
3141 VariantClear(&custom_event->detail);
3142 DOMEvent_destructor(dispex);
3145 typedef struct {
3146 DOMEvent event;
3147 IDOMMessageEvent IDOMMessageEvent_iface;
3148 IHTMLWindow2 *source;
3149 BSTR origin;
3150 VARIANT data;
3151 } DOMMessageEvent;
3153 static inline DOMMessageEvent *impl_from_IDOMMessageEvent(IDOMMessageEvent *iface)
3155 return CONTAINING_RECORD(iface, DOMMessageEvent, IDOMMessageEvent_iface);
3158 DISPEX_IDISPATCH_IMPL(DOMMessageEvent, IDOMMessageEvent, impl_from_IDOMMessageEvent(iface)->event.dispex)
3160 static HRESULT WINAPI DOMMessageEvent_get_data(IDOMMessageEvent *iface, BSTR *p)
3162 DOMMessageEvent *This = impl_from_IDOMMessageEvent(iface);
3164 TRACE("(%p)->(%p)\n", This, p);
3166 if(V_VT(&This->data) == VT_EMPTY) {
3167 *p = SysAllocString(L"");
3168 return S_OK;
3171 if(V_VT(&This->data) != VT_BSTR) {
3172 FIXME("non-string data\n");
3173 return E_NOTIMPL;
3176 return (*p = SysAllocString(V_BSTR(&This->data))) ? S_OK : E_OUTOFMEMORY;
3179 static HRESULT DOMMessageEvent_get_data_hook(DispatchEx *dispex, WORD flags, DISPPARAMS *dp, VARIANT *res,
3180 EXCEPINFO *ei, IServiceProvider *caller)
3182 DOMMessageEvent *This = CONTAINING_RECORD(dispex, DOMMessageEvent, event.dispex);
3184 if(!(flags & DISPATCH_PROPERTYGET) || !res)
3185 return S_FALSE;
3187 TRACE("(%p)->(%p)\n", This, res);
3189 V_VT(res) = VT_EMPTY;
3190 return VariantCopy(res, &This->data);
3193 static HRESULT WINAPI DOMMessageEvent_get_origin(IDOMMessageEvent *iface, BSTR *p)
3195 DOMMessageEvent *This = impl_from_IDOMMessageEvent(iface);
3197 TRACE("(%p)->(%p)\n", This, p);
3199 if(This->origin)
3200 return (*p = SysAllocStringLen(This->origin, SysStringLen(This->origin))) ? S_OK : E_OUTOFMEMORY;
3202 *p = NULL;
3203 return S_OK;
3206 static HRESULT WINAPI DOMMessageEvent_get_source(IDOMMessageEvent *iface, IHTMLWindow2 **p)
3208 DOMMessageEvent *This = impl_from_IDOMMessageEvent(iface);
3210 TRACE("(%p)->(%p)\n", This, p);
3212 if((*p = This->source))
3213 IHTMLWindow2_AddRef(This->source);
3214 return S_OK;
3217 static HRESULT WINAPI DOMMessageEvent_initMessageEvent(IDOMMessageEvent *iface, BSTR type, VARIANT_BOOL can_bubble,
3218 VARIANT_BOOL cancelable, BSTR data, BSTR origin,
3219 BSTR last_event_id, IHTMLWindow2 *source)
3221 DOMMessageEvent *This = impl_from_IDOMMessageEvent(iface);
3222 BSTR new_origin = NULL;
3223 BSTR new_data = NULL;
3224 HRESULT hres;
3226 TRACE("(%p)->(%s %x %x %s %s %s %p)\n", This, debugstr_w(type), can_bubble, cancelable,
3227 debugstr_w(data), debugstr_w(origin), debugstr_w(last_event_id), source);
3229 if(This->event.target) {
3230 TRACE("called on already dispatched event\n");
3231 return S_OK;
3234 if((data && !(new_data = SysAllocString(data))) ||
3235 (origin && !(new_origin = SysAllocString(origin)))) {
3236 hres = E_OUTOFMEMORY;
3237 goto fail;
3240 hres = IDOMEvent_initEvent(&This->event.IDOMEvent_iface, type, can_bubble, cancelable);
3241 if(FAILED(hres))
3242 goto fail;
3244 if(new_data) {
3245 VariantClear(&This->data);
3246 V_VT(&This->data) = VT_BSTR;
3247 V_BSTR(&This->data) = new_data;
3249 if(new_origin) {
3250 SysFreeString(This->origin);
3251 This->origin = new_origin;
3253 if(This->source)
3254 IHTMLWindow2_Release(This->source);
3255 This->source = source;
3256 if(source)
3257 IHTMLWindow2_AddRef(source);
3258 return S_OK;
3260 fail:
3261 SysFreeString(new_origin);
3262 SysFreeString(new_data);
3263 return hres;
3266 static const IDOMMessageEventVtbl DOMMessageEventVtbl = {
3267 DOMMessageEvent_QueryInterface,
3268 DOMMessageEvent_AddRef,
3269 DOMMessageEvent_Release,
3270 DOMMessageEvent_GetTypeInfoCount,
3271 DOMMessageEvent_GetTypeInfo,
3272 DOMMessageEvent_GetIDsOfNames,
3273 DOMMessageEvent_Invoke,
3274 DOMMessageEvent_get_data,
3275 DOMMessageEvent_get_origin,
3276 DOMMessageEvent_get_source,
3277 DOMMessageEvent_initMessageEvent
3280 static DOMMessageEvent *DOMMessageEvent_from_DOMEvent(DOMEvent *event)
3282 return CONTAINING_RECORD(event, DOMMessageEvent, event);
3285 static void *DOMMessageEvent_query_interface(DispatchEx *dispex, REFIID riid)
3287 DOMMessageEvent *message_event = DOMMessageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
3289 if(IsEqualGUID(&IID_IDOMMessageEvent, riid))
3290 return &message_event->IDOMMessageEvent_iface;
3291 return DOMEvent_query_interface(&message_event->event.dispex, riid);
3294 static void DOMMessageEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb)
3296 DOMMessageEvent *message_event = DOMMessageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
3297 DOMEvent_traverse(&message_event->event.dispex, cb);
3298 traverse_variant(&message_event->data, "data", cb);
3299 if(message_event->source)
3300 note_cc_edge((nsISupports*)message_event->source, "MessageEvent.source", cb);
3303 static void DOMMessageEvent_unlink(DispatchEx *dispex)
3305 DOMMessageEvent *message_event = DOMMessageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
3306 DOMEvent_unlink(&message_event->event.dispex);
3307 unlink_variant(&message_event->data);
3308 unlink_ref(&message_event->source);
3311 static void DOMMessageEvent_destructor(DispatchEx *dispex)
3313 DOMMessageEvent *message_event = DOMMessageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
3314 SysFreeString(message_event->origin);
3315 VariantClear(&message_event->data);
3316 DOMEvent_destructor(dispex);
3319 static void DOMMessageEvent_init_dispex_info(dispex_data_t *info, compat_mode_t compat_mode)
3321 static const dispex_hook_t hooks[] = {
3322 {DISPID_IDOMMESSAGEEVENT_DATA, DOMMessageEvent_get_data_hook},
3323 {DISPID_UNKNOWN}
3325 dispex_info_add_interface(info, IDOMMessageEvent_tid, compat_mode >= COMPAT_MODE_IE10 ? hooks : NULL);
3328 typedef struct {
3329 DOMEvent event;
3330 IDOMProgressEvent IDOMProgressEvent_iface;
3331 nsIDOMProgressEvent *nsevent;
3332 BOOL manual_init;
3333 } DOMProgressEvent;
3335 static inline DOMProgressEvent *impl_from_IDOMProgressEvent(IDOMProgressEvent *iface)
3337 return CONTAINING_RECORD(iface, DOMProgressEvent, IDOMProgressEvent_iface);
3340 DISPEX_IDISPATCH_IMPL(DOMProgressEvent, IDOMProgressEvent, impl_from_IDOMProgressEvent(iface)->event.dispex)
3342 static HRESULT WINAPI DOMProgressEvent_get_lengthComputable(IDOMProgressEvent *iface, VARIANT_BOOL *p)
3344 DOMProgressEvent *This = impl_from_IDOMProgressEvent(iface);
3345 nsresult nsres;
3346 cpp_bool b;
3348 TRACE("(%p)->(%p)\n", This, p);
3350 nsres = nsIDOMProgressEvent_GetLengthComputable(This->nsevent, &b);
3351 if(NS_FAILED(nsres))
3352 return map_nsresult(nsres);
3354 *p = b ? VARIANT_TRUE : VARIANT_FALSE;
3355 return S_OK;
3358 static HRESULT WINAPI DOMProgressEvent_get_loaded(IDOMProgressEvent *iface, ULONGLONG *p)
3360 DOMProgressEvent *This = impl_from_IDOMProgressEvent(iface);
3362 TRACE("(%p)->(%p)\n", This, p);
3364 return map_nsresult(nsIDOMProgressEvent_GetLoaded(This->nsevent, p));
3367 static HRESULT WINAPI DOMProgressEvent_get_total(IDOMProgressEvent *iface, ULONGLONG *p)
3369 DOMProgressEvent *This = impl_from_IDOMProgressEvent(iface);
3370 cpp_bool b;
3372 TRACE("(%p)->(%p)\n", This, p);
3374 if(!This->manual_init && (NS_FAILED(nsIDOMProgressEvent_GetLengthComputable(This->nsevent, &b)) || !b)) {
3375 *p = ~0;
3376 return S_OK;
3379 return map_nsresult(nsIDOMProgressEvent_GetTotal(This->nsevent, p));
3382 static HRESULT WINAPI DOMProgressEvent_initProgressEvent(IDOMProgressEvent *iface, BSTR type, VARIANT_BOOL can_bubble,
3383 VARIANT_BOOL cancelable, VARIANT_BOOL lengthComputable,
3384 ULONGLONG loaded, ULONGLONG total)
3386 DOMProgressEvent *This = impl_from_IDOMProgressEvent(iface);
3387 nsAString type_str;
3388 nsresult nsres;
3389 HRESULT hres;
3391 TRACE("(%p)->(%s %x %x %x %s %s)\n", This, debugstr_w(type), can_bubble, cancelable, lengthComputable,
3392 wine_dbgstr_longlong(loaded), wine_dbgstr_longlong(total));
3394 if(This->event.target) {
3395 TRACE("called on already dispatched event\n");
3396 return S_OK;
3399 hres = IDOMEvent_initEvent(&This->event.IDOMEvent_iface, type, can_bubble, cancelable);
3400 if(SUCCEEDED(hres)) {
3401 nsAString_InitDepend(&type_str, type);
3402 nsres = nsIDOMProgressEvent_InitProgressEvent(This->nsevent, &type_str, !!can_bubble, !!cancelable,
3403 !!lengthComputable, loaded, total);
3404 nsAString_Finish(&type_str);
3405 if(NS_FAILED(nsres))
3406 return map_nsresult(nsres);
3407 This->manual_init = TRUE;
3410 return hres;
3413 static const IDOMProgressEventVtbl DOMProgressEventVtbl = {
3414 DOMProgressEvent_QueryInterface,
3415 DOMProgressEvent_AddRef,
3416 DOMProgressEvent_Release,
3417 DOMProgressEvent_GetTypeInfoCount,
3418 DOMProgressEvent_GetTypeInfo,
3419 DOMProgressEvent_GetIDsOfNames,
3420 DOMProgressEvent_Invoke,
3421 DOMProgressEvent_get_lengthComputable,
3422 DOMProgressEvent_get_loaded,
3423 DOMProgressEvent_get_total,
3424 DOMProgressEvent_initProgressEvent
3427 static DOMProgressEvent *DOMProgressEvent_from_DOMEvent(DOMEvent *event)
3429 return CONTAINING_RECORD(event, DOMProgressEvent, event);
3432 static void *DOMProgressEvent_query_interface(DispatchEx *dispex, REFIID riid)
3434 DOMProgressEvent *This = DOMProgressEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
3436 if(IsEqualGUID(&IID_IDOMProgressEvent, riid))
3437 return &This->IDOMProgressEvent_iface;
3438 return DOMEvent_query_interface(&This->event.dispex, riid);
3441 static void DOMProgressEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb)
3443 DOMProgressEvent *This = DOMProgressEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
3444 DOMEvent_traverse(&This->event.dispex, cb);
3445 if(This->nsevent)
3446 note_cc_edge((nsISupports*)This->nsevent, "ProgressEvent.nsevent", cb);
3449 static void DOMProgressEvent_unlink(DispatchEx *dispex)
3451 DOMProgressEvent *This = DOMProgressEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
3452 DOMEvent_unlink(&This->event.dispex);
3453 unlink_ref(&This->nsevent);
3456 static inline DOMStorageEvent *impl_from_IDOMStorageEvent(IDOMStorageEvent *iface)
3458 return CONTAINING_RECORD(iface, DOMStorageEvent, IDOMStorageEvent_iface);
3461 DISPEX_IDISPATCH_IMPL(DOMStorageEvent, IDOMStorageEvent, impl_from_IDOMStorageEvent(iface)->event.dispex)
3463 static HRESULT WINAPI DOMStorageEvent_get_key(IDOMStorageEvent *iface, BSTR *p)
3465 DOMStorageEvent *This = impl_from_IDOMStorageEvent(iface);
3467 TRACE("(%p)->(%p)\n", This, p);
3469 if(This->key)
3470 return (*p = SysAllocStringLen(This->key, SysStringLen(This->key))) ? S_OK : E_OUTOFMEMORY;
3471 *p = NULL;
3472 return S_OK;
3475 static HRESULT WINAPI DOMStorageEvent_get_oldValue(IDOMStorageEvent *iface, BSTR *p)
3477 DOMStorageEvent *This = impl_from_IDOMStorageEvent(iface);
3479 TRACE("(%p)->(%p)\n", This, p);
3481 if(This->old_value)
3482 return (*p = SysAllocStringLen(This->old_value, SysStringLen(This->old_value))) ? S_OK : E_OUTOFMEMORY;
3483 *p = NULL;
3484 return S_OK;
3487 static HRESULT WINAPI DOMStorageEvent_get_newValue(IDOMStorageEvent *iface, BSTR *p)
3489 DOMStorageEvent *This = impl_from_IDOMStorageEvent(iface);
3491 TRACE("(%p)->(%p)\n", This, p);
3493 if(This->new_value)
3494 return (*p = SysAllocStringLen(This->new_value, SysStringLen(This->new_value))) ? S_OK : E_OUTOFMEMORY;
3495 *p = NULL;
3496 return S_OK;
3499 static HRESULT WINAPI DOMStorageEvent_get_url(IDOMStorageEvent *iface, BSTR *p)
3501 DOMStorageEvent *This = impl_from_IDOMStorageEvent(iface);
3503 TRACE("(%p)->(%p)\n", This, p);
3505 if(This->url)
3506 return (*p = SysAllocStringLen(This->url, SysStringLen(This->url))) ? S_OK : E_OUTOFMEMORY;
3507 *p = NULL;
3508 return S_OK;
3511 static HRESULT WINAPI DOMStorageEvent_get_storageArea(IDOMStorageEvent *iface, IHTMLStorage **p)
3513 DOMStorageEvent *This = impl_from_IDOMStorageEvent(iface);
3514 FIXME("(%p)->(%p)\n", This, p);
3515 return E_NOTIMPL;
3518 static HRESULT WINAPI DOMStorageEvent_initStorageEvent(IDOMStorageEvent *iface, BSTR type, VARIANT_BOOL can_bubble,
3519 VARIANT_BOOL cancelable, BSTR keyArg, BSTR oldValueArg,
3520 BSTR newValueArg, BSTR urlArg, IHTMLStorage *storageAreaArg)
3522 DOMStorageEvent *This = impl_from_IDOMStorageEvent(iface);
3523 FIXME("(%p)->(%s %x %x %s %s %s %s %p)\n", This, debugstr_w(type), can_bubble, cancelable,
3524 debugstr_w(keyArg), debugstr_w(oldValueArg), debugstr_w(newValueArg), debugstr_w(urlArg), storageAreaArg);
3525 return E_NOTIMPL;
3528 static const IDOMStorageEventVtbl DOMStorageEventVtbl = {
3529 DOMStorageEvent_QueryInterface,
3530 DOMStorageEvent_AddRef,
3531 DOMStorageEvent_Release,
3532 DOMStorageEvent_GetTypeInfoCount,
3533 DOMStorageEvent_GetTypeInfo,
3534 DOMStorageEvent_GetIDsOfNames,
3535 DOMStorageEvent_Invoke,
3536 DOMStorageEvent_get_key,
3537 DOMStorageEvent_get_oldValue,
3538 DOMStorageEvent_get_newValue,
3539 DOMStorageEvent_get_url,
3540 DOMStorageEvent_get_storageArea,
3541 DOMStorageEvent_initStorageEvent
3544 static void *DOMStorageEvent_query_interface(DispatchEx *dispex, REFIID riid)
3546 DOMStorageEvent *storage_event = DOMStorageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
3548 if(IsEqualGUID(&IID_IDOMStorageEvent, riid))
3549 return &storage_event->IDOMStorageEvent_iface;
3550 return DOMEvent_query_interface(&storage_event->event.dispex, riid);
3553 static void DOMStorageEvent_destructor(DispatchEx *dispex)
3555 DOMStorageEvent *storage_event = DOMStorageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex));
3556 SysFreeString(storage_event->key);
3557 SysFreeString(storage_event->old_value);
3558 SysFreeString(storage_event->new_value);
3559 SysFreeString(storage_event->url);
3560 DOMEvent_destructor(dispex);
3563 static const dispex_static_data_vtbl_t DOMEvent_dispex_vtbl = {
3564 .query_interface = DOMEvent_query_interface,
3565 .destructor = DOMEvent_destructor,
3566 .traverse = DOMEvent_traverse,
3567 .unlink = DOMEvent_unlink
3570 static const tid_t DOMEvent_iface_tids[] = {
3571 IDOMEvent_tid,
3575 static dispex_static_data_t DOMEvent_dispex = {
3576 "Event",
3577 &DOMEvent_dispex_vtbl,
3578 DispDOMEvent_tid,
3579 DOMEvent_iface_tids
3582 static const dispex_static_data_vtbl_t DOMUIEvent_dispex_vtbl = {
3583 .query_interface = DOMUIEvent_query_interface,
3584 .destructor = DOMEvent_destructor,
3585 .traverse = DOMUIEvent_traverse,
3586 .unlink = DOMUIEvent_unlink
3589 static const tid_t DOMUIEvent_iface_tids[] = {
3590 IDOMEvent_tid,
3591 IDOMUIEvent_tid,
3595 static dispex_static_data_t DOMUIEvent_dispex = {
3596 "UIEvent",
3597 &DOMUIEvent_dispex_vtbl,
3598 DispDOMUIEvent_tid,
3599 DOMUIEvent_iface_tids
3602 static const dispex_static_data_vtbl_t DOMMouseEvent_dispex_vtbl = {
3603 .query_interface = DOMMouseEvent_query_interface,
3604 .destructor = DOMEvent_destructor,
3605 .traverse = DOMMouseEvent_traverse,
3606 .unlink = DOMMouseEvent_unlink
3609 static const tid_t DOMMouseEvent_iface_tids[] = {
3610 IDOMEvent_tid,
3611 IDOMUIEvent_tid,
3612 IDOMMouseEvent_tid,
3616 static dispex_static_data_t DOMMouseEvent_dispex = {
3617 "MouseEvent",
3618 &DOMMouseEvent_dispex_vtbl,
3619 DispDOMMouseEvent_tid,
3620 DOMMouseEvent_iface_tids
3623 static const dispex_static_data_vtbl_t DOMKeyboardEvent_dispex_vtbl = {
3624 .query_interface = DOMKeyboardEvent_query_interface,
3625 .destructor = DOMEvent_destructor,
3626 .traverse = DOMKeyboardEvent_traverse,
3627 .unlink = DOMKeyboardEvent_unlink
3630 static const tid_t DOMKeyboardEvent_iface_tids[] = {
3631 IDOMEvent_tid,
3632 IDOMUIEvent_tid,
3633 IDOMKeyboardEvent_tid,
3637 static dispex_static_data_t DOMKeyboardEvent_dispex = {
3638 "KeyboardEvent",
3639 &DOMKeyboardEvent_dispex_vtbl,
3640 DispDOMKeyboardEvent_tid,
3641 DOMKeyboardEvent_iface_tids
3644 static void DOMPageTransitionEvent_init_dispex_info(dispex_data_t *info, compat_mode_t mode)
3646 if(mode >= COMPAT_MODE_IE11)
3647 dispex_info_add_interface(info, IWinePageTransitionEvent_tid, NULL);
3650 static const dispex_static_data_vtbl_t DOMPageTransitionEvent_dispex_vtbl = {
3651 .query_interface = DOMPageTransitionEvent_query_interface,
3652 .destructor = DOMEvent_destructor,
3653 .traverse = DOMEvent_traverse,
3654 .unlink = DOMEvent_unlink
3657 static dispex_static_data_t DOMPageTransitionEvent_dispex = {
3658 "PageTransitionEvent",
3659 &DOMPageTransitionEvent_dispex_vtbl,
3660 DispDOMEvent_tid,
3661 DOMEvent_iface_tids,
3662 DOMPageTransitionEvent_init_dispex_info
3665 static const dispex_static_data_vtbl_t DOMCustomEvent_dispex_vtbl = {
3666 .query_interface = DOMCustomEvent_query_interface,
3667 .destructor = DOMCustomEvent_destructor,
3668 .traverse = DOMCustomEvent_traverse,
3669 .unlink = DOMCustomEvent_unlink
3672 static const tid_t DOMCustomEvent_iface_tids[] = {
3673 IDOMEvent_tid,
3674 IDOMCustomEvent_tid,
3678 static dispex_static_data_t DOMCustomEvent_dispex = {
3679 "CustomEvent",
3680 &DOMCustomEvent_dispex_vtbl,
3681 DispDOMCustomEvent_tid,
3682 DOMCustomEvent_iface_tids
3685 static const dispex_static_data_vtbl_t DOMMessageEvent_dispex_vtbl = {
3686 .query_interface = DOMMessageEvent_query_interface,
3687 .destructor = DOMMessageEvent_destructor,
3688 .traverse = DOMMessageEvent_traverse,
3689 .unlink = DOMMessageEvent_unlink
3692 static const tid_t DOMMessageEvent_iface_tids[] = {
3693 IDOMEvent_tid,
3697 static dispex_static_data_t DOMMessageEvent_dispex = {
3698 "MessageEvent",
3699 &DOMMessageEvent_dispex_vtbl,
3700 DispDOMMessageEvent_tid,
3701 DOMMessageEvent_iface_tids,
3702 DOMMessageEvent_init_dispex_info
3705 static const dispex_static_data_vtbl_t DOMProgressEvent_dispex_vtbl = {
3706 .query_interface = DOMProgressEvent_query_interface,
3707 .destructor = DOMEvent_destructor,
3708 .traverse = DOMProgressEvent_traverse,
3709 .unlink = DOMProgressEvent_unlink
3712 static const tid_t DOMProgressEvent_iface_tids[] = {
3713 IDOMEvent_tid,
3714 IDOMProgressEvent_tid,
3718 static dispex_static_data_t DOMProgressEvent_dispex = {
3719 "ProgressEvent",
3720 &DOMProgressEvent_dispex_vtbl,
3721 DispDOMProgressEvent_tid,
3722 DOMProgressEvent_iface_tids
3725 static const dispex_static_data_vtbl_t DOMStorageEvent_dispex_vtbl = {
3726 .query_interface = DOMStorageEvent_query_interface,
3727 .destructor = DOMStorageEvent_destructor,
3728 .traverse = DOMEvent_traverse,
3729 .unlink = DOMEvent_unlink
3732 static const tid_t DOMStorageEvent_iface_tids[] = {
3733 IDOMEvent_tid,
3734 IDOMStorageEvent_tid,
3738 static dispex_static_data_t DOMStorageEvent_dispex = {
3739 "StorageEvent",
3740 &DOMStorageEvent_dispex_vtbl,
3741 DispDOMStorageEvent_tid,
3742 DOMStorageEvent_iface_tids
3745 static void *event_ctor(unsigned size, dispex_static_data_t *dispex_data, nsIDOMEvent *nsevent, eventid_t event_id,
3746 HTMLInnerWindow *script_global, compat_mode_t compat_mode)
3748 DOMEvent *event = calloc(1, size);
3750 if(!event)
3751 return NULL;
3752 event->IDOMEvent_iface.lpVtbl = &DOMEventVtbl;
3753 event->event_id = event_id;
3754 if(event_id != EVENTID_LAST) {
3755 event->type = wcsdup(event_info[event_id].name);
3756 if(!event->type) {
3757 free(event);
3758 return NULL;
3760 event->bubbles = (event_info[event_id].flags & EVENT_BUBBLES) != 0;
3761 event->cancelable = (event_info[event_id].flags & EVENT_CANCELABLE) != 0;
3763 nsIDOMEvent_AddRef(event->nsevent = nsevent);
3765 event->time_stamp = get_time_stamp();
3767 init_dispatch(&event->dispex, dispex_data, script_global, compat_mode);
3768 return event;
3771 static void fill_parent_ui_event(nsIDOMEvent *nsevent, DOMUIEvent *ui_event)
3773 ui_event->IDOMUIEvent_iface.lpVtbl = &DOMUIEventVtbl;
3774 nsIDOMEvent_QueryInterface(nsevent, &IID_nsIDOMUIEvent, (void**)&ui_event->nsevent);
3777 static DOMEvent *generic_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, HTMLInnerWindow *script_global,
3778 compat_mode_t compat_mode)
3780 return event_ctor(sizeof(DOMEvent), &DOMEvent_dispex, nsevent, event_id, script_global, compat_mode);
3783 static DOMEvent *ui_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, HTMLInnerWindow *script_global,
3784 compat_mode_t compat_mode)
3786 DOMUIEvent *ui_event = event_ctor(sizeof(DOMUIEvent), &DOMUIEvent_dispex, nsevent, event_id, script_global, compat_mode);
3787 if(!ui_event) return NULL;
3788 ui_event->IDOMUIEvent_iface.lpVtbl = &DOMUIEventVtbl;
3789 ui_event->nsevent = iface;
3790 return &ui_event->event;
3793 static DOMEvent *mouse_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, HTMLInnerWindow *script_global,
3794 compat_mode_t compat_mode)
3796 DOMMouseEvent *mouse_event = event_ctor(sizeof(DOMMouseEvent), &DOMMouseEvent_dispex, nsevent, event_id, script_global, compat_mode);
3797 if(!mouse_event) return NULL;
3798 mouse_event->IDOMMouseEvent_iface.lpVtbl = &DOMMouseEventVtbl;
3799 mouse_event->nsevent = iface;
3800 fill_parent_ui_event(nsevent, &mouse_event->ui_event);
3801 return &mouse_event->ui_event.event;
3804 static DOMEvent *keyboard_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, HTMLInnerWindow *script_global,
3805 compat_mode_t compat_mode)
3807 DOMKeyboardEvent *keyboard_event = event_ctor(sizeof(DOMKeyboardEvent), &DOMKeyboardEvent_dispex, nsevent, event_id, script_global,
3808 compat_mode);
3809 if(!keyboard_event) return NULL;
3810 keyboard_event->IDOMKeyboardEvent_iface.lpVtbl = &DOMKeyboardEventVtbl;
3811 keyboard_event->nsevent = iface;
3812 fill_parent_ui_event(nsevent, &keyboard_event->ui_event);
3813 return &keyboard_event->ui_event.event;
3816 static DOMEvent *page_transition_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, HTMLInnerWindow *script_global,
3817 compat_mode_t compat_mode)
3819 DOMPageTransitionEvent *page_transition_event = event_ctor(sizeof(DOMCustomEvent), &DOMPageTransitionEvent_dispex, nsevent, event_id,
3820 script_global, compat_mode);
3821 if(!page_transition_event) return NULL;
3822 page_transition_event->IWinePageTransitionEvent_iface.lpVtbl = &DOMPageTransitionEventVtbl;
3823 return &page_transition_event->event;
3826 static DOMEvent *custom_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, HTMLInnerWindow *script_global,
3827 compat_mode_t compat_mode)
3829 DOMCustomEvent *custom_event = event_ctor(sizeof(DOMCustomEvent), &DOMCustomEvent_dispex, nsevent, event_id, script_global,
3830 compat_mode);
3831 if(!custom_event) return NULL;
3832 custom_event->IDOMCustomEvent_iface.lpVtbl = &DOMCustomEventVtbl;
3833 nsIDOMCustomEvent_Release(iface);
3834 return &custom_event->event;
3837 static DOMEvent *progress_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, HTMLInnerWindow *script_global,
3838 compat_mode_t compat_mode)
3840 DOMProgressEvent *progress_event;
3842 if(!(progress_event = event_ctor(sizeof(DOMProgressEvent), &DOMProgressEvent_dispex, nsevent, event_id, script_global, compat_mode)))
3843 return NULL;
3844 progress_event->IDOMProgressEvent_iface.lpVtbl = &DOMProgressEventVtbl;
3845 progress_event->nsevent = iface;
3846 return &progress_event->event;
3849 static DOMEvent *message_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, HTMLInnerWindow *script_global,
3850 compat_mode_t compat_mode)
3852 DOMMessageEvent *message_event = event_ctor(sizeof(DOMMessageEvent), &DOMMessageEvent_dispex, nsevent, event_id, script_global,
3853 compat_mode);
3854 if(!message_event) return NULL;
3855 message_event->IDOMMessageEvent_iface.lpVtbl = &DOMMessageEventVtbl;
3856 return &message_event->event;
3859 static DOMEvent *storage_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, HTMLInnerWindow *script_global,
3860 compat_mode_t compat_mode)
3862 DOMStorageEvent *storage_event = event_ctor(sizeof(DOMStorageEvent), &DOMStorageEvent_dispex, nsevent, event_id, script_global,
3863 compat_mode);
3864 if(!storage_event) return NULL;
3865 storage_event->IDOMStorageEvent_iface.lpVtbl = &DOMStorageEventVtbl;
3866 return &storage_event->event;
3869 static const struct {
3870 REFIID iid;
3871 DOMEvent *(*ctor)(void *iface, nsIDOMEvent *nsevent, eventid_t, HTMLInnerWindow *sceript_global, compat_mode_t compat_mode);
3872 compat_mode_t min_compat_mode;
3873 } event_types_ctor_table[] = {
3874 [EVENT_TYPE_EVENT] = { NULL, generic_event_ctor },
3875 [EVENT_TYPE_UIEVENT] = { &IID_nsIDOMUIEvent, ui_event_ctor },
3876 [EVENT_TYPE_MOUSE] = { &IID_nsIDOMMouseEvent, mouse_event_ctor },
3877 [EVENT_TYPE_KEYBOARD] = { &IID_nsIDOMKeyEvent, keyboard_event_ctor },
3878 [EVENT_TYPE_CLIPBOARD] = { NULL, generic_event_ctor },
3879 [EVENT_TYPE_FOCUS] = { NULL, generic_event_ctor },
3880 [EVENT_TYPE_DRAG] = { NULL, generic_event_ctor },
3881 [EVENT_TYPE_PAGETRANSITION] = { NULL, page_transition_event_ctor },
3882 [EVENT_TYPE_CUSTOM] = { &IID_nsIDOMCustomEvent, custom_event_ctor },
3883 [EVENT_TYPE_PROGRESS] = { &IID_nsIDOMProgressEvent, progress_event_ctor, COMPAT_MODE_IE10 },
3884 [EVENT_TYPE_MESSAGE] = { NULL, message_event_ctor },
3885 [EVENT_TYPE_STORAGE] = { NULL, storage_event_ctor },
3888 static DOMEvent *alloc_event(nsIDOMEvent *nsevent, HTMLInnerWindow *script_global, compat_mode_t compat_mode, event_type_t event_type,
3889 eventid_t event_id)
3891 void *iface = NULL;
3892 DOMEvent *event;
3894 if(compat_mode < event_types_ctor_table[event_type].min_compat_mode)
3895 event_type = EVENT_TYPE_EVENT;
3897 if(event_types_ctor_table[event_type].iid)
3898 nsIDOMEvent_QueryInterface(nsevent, event_types_ctor_table[event_type].iid, &iface);
3900 /* Transfer the iface ownership to the ctor on success */
3901 if(!(event = event_types_ctor_table[event_type].ctor(iface, nsevent, event_id, script_global, compat_mode)) && iface)
3902 nsISupports_Release(iface);
3903 return event;
3906 HRESULT create_event_from_nsevent(nsIDOMEvent *nsevent, HTMLInnerWindow *script_global, compat_mode_t compat_mode, DOMEvent **ret_event)
3908 event_type_t event_type = EVENT_TYPE_EVENT;
3909 eventid_t event_id = EVENTID_LAST;
3910 DOMEvent *event;
3911 nsAString nsstr;
3912 nsresult nsres;
3913 unsigned i;
3915 nsAString_Init(&nsstr, NULL);
3916 nsres = nsIDOMEvent_GetType(nsevent, &nsstr);
3917 if(NS_SUCCEEDED(nsres)) {
3918 const WCHAR *type;
3919 nsAString_GetData(&nsstr, &type);
3920 event_id = str_to_eid(type);
3921 if(event_id == EVENTID_LAST)
3922 FIXME("unknown event type %s\n", debugstr_w(type));
3923 }else {
3924 ERR("GetType failed: %08lx\n", nsres);
3926 nsAString_Finish(&nsstr);
3928 for(i = 0; i < ARRAY_SIZE(event_types_ctor_table); i++) {
3929 void *iface;
3930 if(event_types_ctor_table[i].iid &&
3931 nsIDOMEvent_QueryInterface(nsevent, event_types_ctor_table[i].iid, &iface) == NS_OK) {
3932 nsISupports_Release(iface);
3933 event_type = i;
3934 break;
3938 event = alloc_event(nsevent, script_global, compat_mode, event_type, event_id);
3939 if(!event)
3940 return E_OUTOFMEMORY;
3942 event->trusted = TRUE;
3943 *ret_event = event;
3944 return S_OK;
3947 HRESULT create_document_event_str(HTMLDocumentNode *doc, const WCHAR *type, IDOMEvent **ret_event)
3949 event_type_t event_type = EVENT_TYPE_EVENT;
3950 nsIDOMEvent *nsevent;
3951 DOMEvent *event;
3952 nsAString nsstr;
3953 nsresult nsres;
3954 unsigned i;
3956 nsAString_InitDepend(&nsstr, type);
3957 nsres = nsIDOMDocument_CreateEvent(doc->dom_document, &nsstr, &nsevent);
3958 nsAString_Finish(&nsstr);
3959 if(NS_FAILED(nsres)) {
3960 FIXME("CreateEvent(%s) failed: %08lx\n", debugstr_w(type), nsres);
3961 return E_FAIL;
3964 for(i = 0; i < ARRAY_SIZE(event_types); i++) {
3965 if(!wcsicmp(type, event_types[i])) {
3966 event_type = i;
3967 break;
3971 event = alloc_event(nsevent, doc->script_global, dispex_compat_mode(&doc->node.event_target.dispex), event_type, EVENTID_LAST);
3972 nsIDOMEvent_Release(nsevent);
3973 if(!event)
3974 return E_OUTOFMEMORY;
3976 *ret_event = &event->IDOMEvent_iface;
3977 return S_OK;
3980 HRESULT create_document_event(HTMLDocumentNode *doc, eventid_t event_id, DOMEvent **ret_event)
3982 nsIDOMEvent *nsevent;
3983 DOMEvent *event;
3984 nsAString nsstr;
3985 nsresult nsres;
3987 nsAString_InitDepend(&nsstr, event_types[event_info[event_id].type]);
3988 nsres = nsIDOMDocument_CreateEvent(doc->dom_document, &nsstr, &nsevent);
3989 nsAString_Finish(&nsstr);
3990 if(NS_FAILED(nsres)) {
3991 FIXME("CreateEvent(%s) failed: %08lx\n", debugstr_w(event_types[event_info[event_id].type]), nsres);
3992 return E_FAIL;
3995 event = alloc_event(nsevent, doc->script_global, doc->document_mode, event_info[event_id].type, event_id);
3996 nsIDOMEvent_Release(nsevent);
3997 if(!event)
3998 return E_OUTOFMEMORY;
4000 event->event_id = event_id;
4001 event->trusted = TRUE;
4002 *ret_event = event;
4003 return S_OK;
4006 HRESULT create_message_event(HTMLDocumentNode *doc, IHTMLWindow2 *source, VARIANT *data, DOMEvent **ret)
4008 URL_COMPONENTSW url = { sizeof(url) };
4009 DOMMessageEvent *message_event;
4010 IHTMLLocation *location;
4011 DOMEvent *event;
4012 HRESULT hres;
4013 BSTR origin;
4015 hres = IHTMLWindow2_get_location(source, &location);
4016 if(FAILED(hres))
4017 return hres;
4019 hres = IHTMLLocation_get_href(location, &origin);
4020 IHTMLLocation_Release(location);
4021 if(FAILED(hres))
4022 return hres;
4024 url.dwUrlPathLength = 1;
4025 if(origin && InternetCrackUrlW(origin, 0, 0, &url)) {
4026 BSTR tmp = SysAllocStringLen(origin, url.lpszUrlPath - origin);
4027 SysFreeString(origin);
4028 if(!tmp)
4029 return E_OUTOFMEMORY;
4030 origin = tmp;
4033 hres = create_document_event(doc, EVENTID_MESSAGE, &event);
4034 if(FAILED(hres)) {
4035 SysFreeString(origin);
4036 return hres;
4038 message_event = DOMMessageEvent_from_DOMEvent(event);
4039 message_event->origin = origin;
4041 V_VT(&message_event->data) = VT_EMPTY;
4042 hres = VariantCopy(&message_event->data, data);
4043 if(FAILED(hres)) {
4044 IDOMEvent_Release(&event->IDOMEvent_iface);
4045 return hres;
4048 message_event->source = source;
4049 IHTMLWindow2_AddRef(message_event->source);
4051 *ret = event;
4052 return S_OK;
4055 HRESULT create_storage_event(HTMLDocumentNode *doc, BSTR key, BSTR old_value, BSTR new_value,
4056 const WCHAR *url, BOOL commit, DOMEvent **ret)
4058 DOMStorageEvent *storage_event;
4059 DOMEvent *event;
4060 HRESULT hres;
4062 hres = create_document_event(doc, commit ? EVENTID_STORAGECOMMIT : EVENTID_STORAGE, &event);
4063 if(FAILED(hres))
4064 return hres;
4065 storage_event = DOMStorageEvent_from_DOMEvent(event);
4067 if(!commit) {
4068 if((key && !(storage_event->key = SysAllocString(key))) ||
4069 (old_value && !(storage_event->old_value = SysAllocString(old_value))) ||
4070 (new_value && !(storage_event->new_value = SysAllocString(new_value)))) {
4071 IDOMEvent_Release(&event->IDOMEvent_iface);
4072 return E_OUTOFMEMORY;
4076 if(url && !(storage_event->url = SysAllocString(url))) {
4077 IDOMEvent_Release(&event->IDOMEvent_iface);
4078 return E_OUTOFMEMORY;
4081 *ret = event;
4082 return S_OK;
4085 HRESULT call_disp_func(IDispatch *disp, DISPPARAMS *dp, VARIANT *retv)
4087 IDispatchEx *dispex;
4088 EXCEPINFO ei;
4089 HRESULT hres;
4091 memset(&ei, 0, sizeof(ei));
4093 hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
4094 if(SUCCEEDED(hres)) {
4095 hres = IDispatchEx_InvokeEx(dispex, 0, GetUserDefaultLCID(), DISPATCH_METHOD, dp, retv, &ei, NULL);
4096 IDispatchEx_Release(dispex);
4097 }else {
4098 TRACE("Could not get IDispatchEx interface: %08lx\n", hres);
4099 hres = IDispatch_Invoke(disp, 0, &IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD,
4100 dp, retv, &ei, NULL);
4103 return hres;
4106 static HRESULT call_cp_func(IDispatch *disp, DISPID dispid, IHTMLEventObj *event_obj, VARIANT *retv)
4108 DISPPARAMS dp = {NULL,NULL,0,0};
4109 VARIANT event_arg;
4110 UINT argerr;
4111 EXCEPINFO ei;
4113 TRACE("%p,%ld,%p,%p\n", disp, dispid, event_obj, retv);
4115 if(event_obj) {
4116 V_VT(&event_arg) = VT_DISPATCH;
4117 V_DISPATCH(&event_arg) = (IDispatch*)event_obj;
4118 dp.rgvarg = &event_arg;
4119 dp.cArgs = 1;
4122 memset(&ei, 0, sizeof(ei));
4123 return IDispatch_Invoke(disp, dispid, &IID_NULL, 0, DISPATCH_METHOD, &dp, retv, &ei, &argerr);
4126 static BOOL use_event_quirks(EventTarget *event_target)
4128 return dispex_compat_mode(&event_target->dispex) < COMPAT_MODE_IE9;
4131 static BOOL is_cp_event(cp_static_data_t *data, DISPID dispid)
4133 int min, max, i;
4134 HRESULT hres;
4136 if(!data || dispid == DISPID_UNKNOWN)
4137 return FALSE;
4139 if(!data->ids) {
4140 hres = get_dispids(data->tid, &data->id_cnt, &data->ids);
4141 if(FAILED(hres))
4142 return FALSE;
4145 min = 0;
4146 max = data->id_cnt-1;
4147 while(min <= max) {
4148 i = (min+max)/2;
4149 if(data->ids[i] == dispid)
4150 return TRUE;
4152 if(data->ids[i] < dispid)
4153 min = i+1;
4154 else
4155 max = i-1;
4158 return FALSE;
4161 static void call_event_handlers(EventTarget *event_target, DOMEvent *event, dispatch_mode_t dispatch_mode)
4163 const listener_container_t *container = get_listener_container(event_target, event->type, FALSE);
4164 const event_target_vtbl_t *vtbl = dispex_get_vtbl(&event_target->dispex);
4165 event_listener_t *listener, listeners_buf[8], *listeners = listeners_buf;
4166 unsigned listeners_cnt, listeners_size;
4167 ConnectionPointContainer *cp_container = NULL;
4168 BOOL skip_onevent_listener = FALSE;
4169 VARIANT v;
4170 HRESULT hres;
4172 assert(!event->current_target);
4173 event->current_target = event_target;
4175 if(container && !list_empty(&container->listeners) && event->phase != DEP_CAPTURING_PHASE) {
4176 listener = LIST_ENTRY(list_tail(&container->listeners), event_listener_t, entry);
4177 if(listener && listener->function && listener->type == LISTENER_TYPE_ONEVENT
4178 && use_event_quirks(event_target)) {
4179 DISPID named_arg = DISPID_THIS;
4180 VARIANTARG arg;
4181 DISPPARAMS dp = {&arg, &named_arg, 1, 1};
4183 skip_onevent_listener = TRUE;
4185 V_VT(&arg) = VT_DISPATCH;
4186 V_DISPATCH(&arg) = (IDispatch*)&event_target->dispex.IWineJSDispatchHost_iface;
4187 V_VT(&v) = VT_EMPTY;
4188 if(vtbl->get_dispatch_this)
4189 V_DISPATCH(&arg) = vtbl->get_dispatch_this(&event_target->dispex);
4190 IDispatch_AddRef(V_DISPATCH(&arg));
4192 TRACE("%p %s >>>\n", event_target, debugstr_w(event->type));
4193 hres = call_disp_func(listener->function, &dp, &v);
4194 IDispatch_Release(V_DISPATCH(&arg));
4196 if(hres == S_OK) {
4197 TRACE("%p %s <<< %s\n", event_target, debugstr_w(event->type), debugstr_variant(&v));
4199 if(event->cancelable) {
4200 if(V_VT(&v) == VT_BOOL) {
4201 if(!V_BOOL(&v))
4202 IDOMEvent_preventDefault(&event->IDOMEvent_iface);
4203 }else if(V_VT(&v) != VT_EMPTY) {
4204 FIXME("unhandled result %s\n", debugstr_variant(&v));
4207 VariantClear(&v);
4208 }else {
4209 WARN("%p %s <<< %08lx\n", event_target, debugstr_w(event->type), hres);
4214 listeners_cnt = 0;
4215 listeners_size = ARRAY_SIZE(listeners_buf);
4217 if(container) {
4218 LIST_FOR_EACH_ENTRY(listener, &container->listeners, event_listener_t, entry) {
4219 if(!listener->function)
4220 continue;
4221 switch(listener->type) {
4222 case LISTENER_TYPE_ONEVENT:
4223 if(skip_onevent_listener || event->phase == DEP_CAPTURING_PHASE)
4224 continue;
4225 break;
4226 case LISTENER_TYPE_CAPTURE:
4227 if(event->phase == DEP_BUBBLING_PHASE || dispatch_mode == DISPATCH_LEGACY)
4228 continue;
4229 break;
4230 case LISTENER_TYPE_BUBBLE:
4231 if(event->phase == DEP_CAPTURING_PHASE || dispatch_mode == DISPATCH_LEGACY)
4232 continue;
4233 break;
4234 case LISTENER_TYPE_ATTACHED:
4235 if(event->phase == DEP_CAPTURING_PHASE || dispatch_mode == DISPATCH_STANDARD)
4236 continue;
4237 break;
4240 if(listeners_cnt == listeners_size) {
4241 event_listener_t *new_listeners;
4242 if(listeners == listeners_buf) {
4243 new_listeners = malloc(listeners_size * 2 * sizeof(*new_listeners));
4244 if(!new_listeners)
4245 break;
4246 memcpy(new_listeners, listeners, listeners_cnt * sizeof(*listeners));
4247 }else {
4248 new_listeners = realloc(listeners, listeners_size * 2 * sizeof(*new_listeners));
4250 listeners = new_listeners;
4251 listeners_size *= 2;
4254 listeners[listeners_cnt].type = listener->type;
4255 IDispatch_AddRef(listeners[listeners_cnt].function = listener->function);
4256 listeners_cnt++;
4260 for(listener = listeners; !event->stop_immediate_propagation
4261 && listener < listeners + listeners_cnt; listener++) {
4262 if(listener->type != LISTENER_TYPE_ATTACHED) {
4263 DISPID named_arg = DISPID_THIS;
4264 VARIANTARG args[2];
4265 DISPPARAMS dp = {args, &named_arg, 2, 1};
4267 V_VT(args) = VT_DISPATCH;
4268 V_DISPATCH(args) = (IDispatch*)&event_target->dispex.IWineJSDispatchHost_iface;
4269 if(vtbl->get_dispatch_this)
4270 V_DISPATCH(args) = vtbl->get_dispatch_this(&event_target->dispex);
4271 IDispatch_AddRef(V_DISPATCH(args));
4273 V_VT(args+1) = VT_DISPATCH;
4274 V_DISPATCH(args+1) = dispatch_mode == DISPATCH_LEGACY
4275 ? (IDispatch*)event->event_obj : (IDispatch*)&event->IDOMEvent_iface;
4276 V_VT(&v) = VT_EMPTY;
4278 TRACE("%p %s >>>\n", event_target, debugstr_w(event->type));
4279 hres = call_disp_func(listener->function, &dp, &v);
4280 IDispatch_Release(V_DISPATCH(args));
4282 if(hres == S_OK) {
4283 TRACE("%p %s <<< %s\n", event_target, debugstr_w(event->type),
4284 debugstr_variant(&v));
4286 if(event->cancelable) {
4287 if(V_VT(&v) == VT_BOOL) {
4288 if(!V_BOOL(&v))
4289 IDOMEvent_preventDefault(&event->IDOMEvent_iface);
4290 }else if(V_VT(&v) != VT_EMPTY) {
4291 FIXME("unhandled result %s\n", debugstr_variant(&v));
4294 VariantClear(&v);
4295 }else {
4296 WARN("%p %s <<< %08lx\n", event_target, debugstr_w(event->type), hres);
4298 }else {
4299 VARIANTARG arg;
4300 DISPPARAMS dp = {&arg, NULL, 1, 0};
4302 V_VT(&arg) = VT_DISPATCH;
4303 V_DISPATCH(&arg) = (IDispatch*)event->event_obj;
4304 V_VT(&v) = VT_EMPTY;
4306 TRACE("%p %s attached >>>\n", event_target, debugstr_w(event->type));
4307 hres = call_disp_func(listener->function, &dp, &v);
4308 if(hres == S_OK) {
4309 TRACE("%p %s attached <<<\n", event_target, debugstr_w(event->type));
4311 if(event->cancelable) {
4312 if(V_VT(&v) == VT_BOOL) {
4313 if(!V_BOOL(&v))
4314 IDOMEvent_preventDefault(&event->IDOMEvent_iface);
4315 }else if(V_VT(&v) != VT_EMPTY) {
4316 FIXME("unhandled result %s\n", debugstr_variant(&v));
4319 VariantClear(&v);
4320 }else {
4321 WARN("%p %s attached <<< %08lx\n", event_target, debugstr_w(event->type), hres);
4326 for(listener = listeners; listener < listeners + listeners_cnt; listener++)
4327 IDispatch_Release(listener->function);
4328 if(listeners != listeners_buf)
4329 free(listeners);
4331 if(event->phase != DEP_CAPTURING_PHASE && event_info[event->event_id].dispid && vtbl->get_cp_container)
4332 cp_container = vtbl->get_cp_container(&event_target->dispex);
4333 if(cp_container) {
4334 if(cp_container->cps) {
4335 ConnectionPoint *cp;
4336 unsigned i, j;
4338 for(j=0; cp_container->cp_entries[j].riid; j++) {
4339 cp = cp_container->cps + j;
4340 if(!cp->sinks_size || !is_cp_event(cp->data, event_info[event->event_id].dispid))
4341 continue;
4343 for(i=0; i < cp->sinks_size; i++) {
4344 if(!cp->sinks[i].disp)
4345 continue;
4347 V_VT(&v) = VT_EMPTY;
4349 TRACE("%p cp %s [%u] >>>\n", event_target, debugstr_w(event->type), i);
4350 hres = call_cp_func(cp->sinks[i].disp, event_info[event->event_id].dispid,
4351 cp->data->pass_event_arg ? event->event_obj : NULL, &v);
4352 if(hres == S_OK) {
4353 TRACE("%p cp %s [%u] <<<\n", event_target, debugstr_w(event->type), i);
4355 if(event->cancelable) {
4356 if(V_VT(&v) == VT_BOOL) {
4357 if(!V_BOOL(&v))
4358 IDOMEvent_preventDefault(&event->IDOMEvent_iface);
4359 }else if(V_VT(&v) != VT_EMPTY) {
4360 FIXME("unhandled result %s\n", debugstr_variant(&v));
4363 VariantClear(&v);
4364 }else {
4365 WARN("%p cp %s [%u] <<< %08lx\n", event_target, debugstr_w(event->type), i, hres);
4370 IConnectionPointContainer_Release(&cp_container->IConnectionPointContainer_iface);
4373 event->current_target = NULL;
4376 static HRESULT dispatch_event_object(EventTarget *event_target, DOMEvent *event,
4377 dispatch_mode_t dispatch_mode, VARIANT_BOOL *r)
4379 EventTarget *target_chain_buf[8], **target_chain = target_chain_buf;
4380 unsigned chain_cnt, chain_buf_size, i;
4381 const event_target_vtbl_t *vtbl, *target_vtbl;
4382 HTMLEventObj *event_obj_ref = NULL;
4383 IHTMLEventObj *prev_event = NULL;
4384 EventTarget *iter;
4385 HRESULT hres;
4387 TRACE("(%p) %s\n", event_target, debugstr_w(event->type));
4389 if(!event->type) {
4390 FIXME("Uninitialized event.\n");
4391 return E_FAIL;
4394 if(event->current_target) {
4395 FIXME("event is being dispatched.\n");
4396 return E_FAIL;
4399 iter = event_target;
4400 IEventTarget_AddRef(&event_target->IEventTarget_iface);
4402 chain_cnt = 0;
4403 chain_buf_size = ARRAY_SIZE(target_chain_buf);
4405 do {
4406 if(chain_cnt == chain_buf_size) {
4407 EventTarget **new_chain;
4408 if(target_chain == target_chain_buf) {
4409 new_chain = malloc(chain_buf_size * 2 * sizeof(*new_chain));
4410 if(!new_chain)
4411 break;
4412 memcpy(new_chain, target_chain, chain_buf_size * sizeof(*new_chain));
4413 }else {
4414 new_chain = realloc(target_chain, chain_buf_size * 2 * sizeof(*new_chain));
4415 if(!new_chain)
4416 break;
4418 chain_buf_size *= 2;
4419 target_chain = new_chain;
4422 target_chain[chain_cnt++] = iter;
4424 if(!(vtbl = dispex_get_vtbl(&iter->dispex))->get_parent_event_target)
4425 break;
4426 iter = vtbl->get_parent_event_target(&iter->dispex);
4427 } while(iter);
4429 if(!event->event_obj && !event->no_event_obj) {
4430 event_obj_ref = alloc_event_obj(event, NULL);
4431 if(event_obj_ref)
4432 event->event_obj = &event_obj_ref->IHTMLEventObj_iface;
4435 target_vtbl = dispex_get_vtbl(&event_target->dispex);
4436 if(target_vtbl->set_current_event)
4437 prev_event = target_vtbl->set_current_event(&event_target->dispex, event->event_obj);
4439 if(event->target)
4440 IEventTarget_Release(&event->target->IEventTarget_iface);
4441 event->target = event_target;
4442 IEventTarget_AddRef(&event_target->IEventTarget_iface);
4444 event->phase = DEP_CAPTURING_PHASE;
4446 if(event_info[event->event_id].flags & EVENT_HASDEFAULTHANDLERS) {
4447 for(i = 0; i < chain_cnt; i++) {
4448 vtbl = dispex_get_vtbl(&target_chain[i]->dispex);
4449 if(!vtbl->pre_handle_event)
4450 continue;
4451 hres = vtbl->pre_handle_event(&target_chain[i]->dispex, event);
4452 if(FAILED(hres) || event->stop_propagation)
4453 break;
4457 i = chain_cnt-1;
4458 while(!event->stop_propagation && i)
4459 call_event_handlers(target_chain[i--], event, dispatch_mode);
4461 if(!event->stop_propagation) {
4462 event->phase = DEP_AT_TARGET;
4463 call_event_handlers(target_chain[0], event, dispatch_mode);
4466 if(event->bubbles) {
4467 event->phase = DEP_BUBBLING_PHASE;
4468 for(i = 1; !event->stop_propagation && i < chain_cnt; i++)
4469 call_event_handlers(target_chain[i], event, dispatch_mode);
4472 if(r)
4473 *r = variant_bool(!event->prevent_default);
4475 if(target_vtbl->set_current_event) {
4476 IHTMLEventObj *prev = target_vtbl->set_current_event(&event_target->dispex, prev_event);
4477 if(prev)
4478 IHTMLEventObj_Release(prev);
4481 if(prev_event)
4482 IHTMLEventObj_Release(prev_event);
4484 if(event_info[event->event_id].flags & EVENT_HASDEFAULTHANDLERS) {
4485 BOOL prevent_default = event->prevent_default;
4486 for(i = 0; !prevent_default && i < chain_cnt; i++) {
4487 vtbl = dispex_get_vtbl(&target_chain[i]->dispex);
4488 if(!vtbl->handle_event)
4489 continue;
4490 hres = vtbl->handle_event(&target_chain[i]->dispex, event, &prevent_default);
4491 if(FAILED(hres) || event->stop_propagation)
4492 break;
4493 if(prevent_default)
4494 nsIDOMEvent_PreventDefault(event->nsevent);
4498 event->prevent_default = FALSE;
4499 if(event_obj_ref) {
4500 event->event_obj = NULL;
4501 IHTMLEventObj_Release(&event_obj_ref->IHTMLEventObj_iface);
4504 for(i = 0; i < chain_cnt; i++)
4505 IEventTarget_Release(&target_chain[i]->IEventTarget_iface);
4506 if(target_chain != target_chain_buf)
4507 free(target_chain);
4509 return S_OK;
4512 void dispatch_event(EventTarget *event_target, DOMEvent *event)
4514 dispatch_event_object(event_target, event, DISPATCH_BOTH, NULL);
4517 * We may have registered multiple Gecko listeners for the same event type,
4518 * but we already dispatched event to all relevant targets. Stop event
4519 * propagation here to avoid events being dispatched multiple times.
4521 if(event_info[event->event_id].flags & EVENT_BIND_TO_TARGET)
4522 nsIDOMEvent_StopPropagation(event->nsevent);
4525 HRESULT fire_event(HTMLDOMNode *node, const WCHAR *event_name, VARIANT *event_var, VARIANT_BOOL *cancelled)
4527 HTMLEventObj *event_obj = NULL;
4528 eventid_t eid;
4529 HRESULT hres = S_OK;
4531 eid = attr_to_eid(event_name);
4532 if(eid == EVENTID_LAST) {
4533 WARN("unknown event %s\n", debugstr_w(event_name));
4534 return E_INVALIDARG;
4537 if(event_var && V_VT(event_var) != VT_EMPTY && V_VT(event_var) != VT_ERROR) {
4538 if(V_VT(event_var) != VT_DISPATCH) {
4539 FIXME("event_var %s not supported\n", debugstr_variant(event_var));
4540 return E_NOTIMPL;
4543 if(V_DISPATCH(event_var)) {
4544 IHTMLEventObj *event_iface;
4546 hres = IDispatch_QueryInterface(V_DISPATCH(event_var), &IID_IHTMLEventObj, (void**)&event_iface);
4547 if(FAILED(hres)) {
4548 FIXME("No IHTMLEventObj iface\n");
4549 return hres;
4552 event_obj = unsafe_impl_from_IHTMLEventObj(event_iface);
4553 if(!event_obj) {
4554 ERR("Not our IHTMLEventObj?\n");
4555 IHTMLEventObj_Release(event_iface);
4556 return E_FAIL;
4561 if(!event_obj) {
4562 event_obj = alloc_event_obj(NULL, node->doc->script_global);
4563 if(!event_obj)
4564 return E_OUTOFMEMORY;
4567 if(!event_obj->event)
4568 hres = create_document_event(node->doc, eid, &event_obj->event);
4570 if(SUCCEEDED(hres)) {
4571 event_obj->event->event_obj = &event_obj->IHTMLEventObj_iface;
4572 dispatch_event_object(&node->event_target, event_obj->event, DISPATCH_LEGACY, NULL);
4573 event_obj->event->event_obj = NULL;
4576 IHTMLEventObj_Release(&event_obj->IHTMLEventObj_iface);
4577 if(FAILED(hres))
4578 return hres;
4580 *cancelled = VARIANT_TRUE; /* FIXME */
4581 return S_OK;
4584 HRESULT ensure_doc_nsevent_handler(HTMLDocumentNode *doc, nsIDOMNode *nsnode, eventid_t eid)
4586 TRACE("%s\n", debugstr_w(event_info[eid].name));
4588 if(!doc->dom_document)
4589 return S_OK;
4591 switch(eid) {
4592 case EVENTID_FOCUSIN:
4593 doc->event_vector[eid] = TRUE;
4594 eid = EVENTID_FOCUS;
4595 break;
4596 case EVENTID_FOCUSOUT:
4597 doc->event_vector[eid] = TRUE;
4598 eid = EVENTID_BLUR;
4599 break;
4600 default:
4601 break;
4604 if(event_info[eid].flags & EVENT_DEFAULTLISTENER) {
4605 nsnode = NULL;
4606 }else if(!(event_info[eid].flags & EVENT_BIND_TO_TARGET)) {
4607 return S_OK;
4610 if(!nsnode || nsnode == doc->node.nsnode) {
4611 if(doc->event_vector[eid])
4612 return S_OK;
4613 doc->event_vector[eid] = TRUE;
4616 add_nsevent_listener(doc, nsnode, event_info[eid].name);
4617 return S_OK;
4620 void detach_events(HTMLDocumentNode *doc)
4622 if(doc->event_vector) {
4623 int i;
4625 for(i=0; i < EVENTID_LAST; i++) {
4626 if(doc->event_vector[i]) {
4627 detach_nsevent(doc, event_info[i].name);
4628 doc->event_vector[i] = FALSE;
4633 release_nsevents(doc);
4636 static HRESULT get_event_dispex_ref(EventTarget *event_target, eventid_t eid, BOOL alloc, VARIANT **ret)
4638 WCHAR buf[64];
4639 buf[0] = 'o';
4640 buf[1] = 'n';
4641 lstrcpyW(buf+2, event_info[eid].name);
4642 return dispex_get_dprop_ref(&event_target->dispex, buf, alloc, ret);
4645 static event_listener_t *get_onevent_listener(EventTarget *event_target, eventid_t eid, BOOL alloc)
4647 listener_container_t *container;
4648 event_listener_t *listener;
4650 container = get_listener_container(event_target, event_info[eid].name, alloc);
4651 if(!container)
4652 return NULL;
4654 LIST_FOR_EACH_ENTRY_REV(listener, &container->listeners, event_listener_t, entry) {
4655 if(listener->type == LISTENER_TYPE_ONEVENT)
4656 return listener;
4659 if(!alloc)
4660 return NULL;
4662 listener = malloc(sizeof(*listener));
4663 if(!listener)
4664 return NULL;
4666 listener->type = LISTENER_TYPE_ONEVENT;
4667 listener->function = NULL;
4668 list_add_tail(&container->listeners, &listener->entry);
4669 return listener;
4672 static void remove_event_handler(EventTarget *event_target, eventid_t eid)
4674 event_listener_t *listener;
4675 VARIANT *store;
4676 HRESULT hres;
4678 hres = get_event_dispex_ref(event_target, eid, FALSE, &store);
4679 if(SUCCEEDED(hres))
4680 VariantClear(store);
4682 listener = get_onevent_listener(event_target, eid, FALSE);
4683 if(listener && listener->function) {
4684 IDispatch_Release(listener->function);
4685 listener->function = NULL;
4689 static HRESULT set_event_handler_disp(EventTarget *event_target, eventid_t eid, IDispatch *disp)
4691 event_listener_t *listener;
4693 if(event_info[eid].flags & EVENT_FIXME)
4694 FIXME("unimplemented event %s\n", debugstr_w(event_info[eid].name));
4696 remove_event_handler(event_target, eid);
4697 if(!disp)
4698 return S_OK;
4700 listener = get_onevent_listener(event_target, eid, TRUE);
4701 if(!listener)
4702 return E_OUTOFMEMORY;
4704 if(listener->function)
4705 IDispatch_Release(listener->function);
4707 IDispatch_AddRef(listener->function = disp);
4708 return S_OK;
4711 HRESULT set_event_handler(EventTarget *event_target, eventid_t eid, VARIANT *var)
4713 switch(V_VT(var)) {
4714 case VT_EMPTY:
4715 if(use_event_quirks(event_target)) {
4716 WARN("attempt to set to VT_EMPTY in quirks mode\n");
4717 return E_NOTIMPL;
4719 /* fall through */
4720 case VT_NULL:
4721 remove_event_handler(event_target, eid);
4722 return S_OK;
4724 case VT_DISPATCH:
4725 return set_event_handler_disp(event_target, eid, V_DISPATCH(var));
4727 case VT_BSTR: {
4728 VARIANT *v;
4729 HRESULT hres;
4731 if(!use_event_quirks(event_target))
4732 FIXME("Setting to string %s not supported\n", debugstr_w(V_BSTR(var)));
4735 * Setting event handler to string is a rare case and we don't want to
4736 * complicate nor increase memory of listener_container_t for that. Instead,
4737 * we store the value in DispatchEx, which can already handle custom
4738 * properties.
4740 remove_event_handler(event_target, eid);
4742 hres = get_event_dispex_ref(event_target, eid, TRUE, &v);
4743 if(FAILED(hres))
4744 return hres;
4746 V_BSTR(v) = SysAllocString(V_BSTR(var));
4747 if(!V_BSTR(v))
4748 return E_OUTOFMEMORY;
4749 V_VT(v) = VT_BSTR;
4750 return S_OK;
4753 default:
4754 FIXME("not handler %s\n", debugstr_variant(var));
4755 return E_NOTIMPL;
4758 return S_OK;
4761 HRESULT get_event_handler(EventTarget *event_target, eventid_t eid, VARIANT *var)
4763 event_listener_t *listener;
4764 VARIANT *v;
4765 HRESULT hres;
4767 hres = get_event_dispex_ref(event_target, eid, FALSE, &v);
4768 if(SUCCEEDED(hres) && V_VT(v) != VT_EMPTY) {
4769 V_VT(var) = VT_EMPTY;
4770 return VariantCopy(var, v);
4773 listener = get_onevent_listener(event_target, eid, FALSE);
4774 if(listener && listener->function) {
4775 V_VT(var) = VT_DISPATCH;
4776 V_DISPATCH(var) = listener->function;
4777 IDispatch_AddRef(V_DISPATCH(var));
4778 }else {
4779 V_VT(var) = VT_NULL;
4782 return S_OK;
4785 HRESULT attach_event(EventTarget *event_target, BSTR name, IDispatch *disp, VARIANT_BOOL *res)
4787 listener_container_t *container;
4788 event_listener_t *listener;
4789 eventid_t eid;
4791 if(!disp) {
4792 *res = VARIANT_FALSE;
4793 return S_OK;
4796 eid = attr_to_eid(name);
4797 if(eid == EVENTID_LAST) {
4798 WARN("Unknown event\n");
4799 *res = VARIANT_TRUE;
4800 return S_OK;
4803 container = get_listener_container(event_target, event_info[eid].name, TRUE);
4804 if(!container)
4805 return E_OUTOFMEMORY;
4807 listener = malloc(sizeof(*listener));
4808 if(!listener)
4809 return E_OUTOFMEMORY;
4811 listener->type = LISTENER_TYPE_ATTACHED;
4812 IDispatch_AddRef(listener->function = disp);
4813 if(use_event_quirks(event_target))
4814 list_add_head(&container->listeners, &listener->entry);
4815 else
4816 list_add_tail(&container->listeners, &listener->entry);
4818 *res = VARIANT_TRUE;
4819 return S_OK;
4822 HRESULT detach_event(EventTarget *event_target, BSTR name, IDispatch *disp)
4824 eventid_t eid;
4826 eid = attr_to_eid(name);
4827 if(eid == EVENTID_LAST) {
4828 WARN("Unknown event\n");
4829 return S_OK;
4832 remove_event_listener(event_target, event_info[eid].name, LISTENER_TYPE_ATTACHED, disp);
4833 return S_OK;
4836 void bind_target_event(HTMLDocumentNode *doc, EventTarget *event_target, const WCHAR *event, IDispatch *disp)
4838 eventid_t eid;
4840 TRACE("(%p %p %s %p)\n", doc, event_target, debugstr_w(event), disp);
4842 eid = attr_to_eid(event);
4843 if(eid == EVENTID_LAST) {
4844 WARN("Unsupported event %s\n", debugstr_w(event));
4845 return;
4848 set_event_handler_disp(event_target, eid, disp);
4851 void update_doc_cp_events(HTMLDocumentNode *doc, cp_static_data_t *cp)
4853 int i;
4855 for(i=0; i < EVENTID_LAST; i++) {
4856 if((event_info[i].flags & EVENT_DEFAULTLISTENER) && is_cp_event(cp, event_info[i].dispid))
4857 ensure_doc_nsevent_handler(doc, NULL, i);
4861 void check_event_attr(HTMLDocumentNode *doc, nsIDOMElement *nselem)
4863 nsIDOMMozNamedAttrMap *attr_map;
4864 const PRUnichar *name, *value;
4865 nsAString name_str, value_str;
4866 HTMLDOMNode *node = NULL;
4867 cpp_bool has_attrs;
4868 nsIDOMAttr *attr;
4869 IDispatch *disp;
4870 UINT32 length, i;
4871 eventid_t eid;
4872 nsresult nsres;
4873 HRESULT hres;
4875 nsres = nsIDOMElement_HasAttributes(nselem, &has_attrs);
4876 if(NS_FAILED(nsres) || !has_attrs)
4877 return;
4879 nsres = nsIDOMElement_GetAttributes(nselem, &attr_map);
4880 if(NS_FAILED(nsres))
4881 return;
4883 nsres = nsIDOMMozNamedAttrMap_GetLength(attr_map, &length);
4884 assert(nsres == NS_OK);
4886 nsAString_Init(&name_str, NULL);
4887 nsAString_Init(&value_str, NULL);
4889 for(i = 0; i < length; i++) {
4890 nsres = nsIDOMMozNamedAttrMap_Item(attr_map, i, &attr);
4891 if(NS_FAILED(nsres))
4892 continue;
4894 nsres = nsIDOMAttr_GetName(attr, &name_str);
4895 if(NS_FAILED(nsres)) {
4896 nsIDOMAttr_Release(attr);
4897 continue;
4900 nsAString_GetData(&name_str, &name);
4901 eid = attr_to_eid(name);
4902 if(eid == EVENTID_LAST) {
4903 nsIDOMAttr_Release(attr);
4904 continue;
4907 nsres = nsIDOMAttr_GetValue(attr, &value_str);
4908 nsIDOMAttr_Release(attr);
4909 if(NS_FAILED(nsres))
4910 continue;
4912 nsAString_GetData(&value_str, &value);
4913 if(!*value)
4914 continue;
4916 TRACE("%p.%s = %s\n", nselem, debugstr_w(name), debugstr_w(value));
4918 disp = script_parse_event(doc->window, value);
4919 if(!disp)
4920 continue;
4922 if(!node) {
4923 hres = get_node((nsIDOMNode*)nselem, TRUE, &node);
4924 if(FAILED(hres)) {
4925 IDispatch_Release(disp);
4926 break;
4930 set_event_handler_disp(get_node_event_prop_target(node, eid), eid, disp);
4931 IDispatch_Release(disp);
4934 if(node)
4935 node_release(node);
4936 nsAString_Finish(&name_str);
4937 nsAString_Finish(&value_str);
4938 nsIDOMMozNamedAttrMap_Release(attr_map);
4941 HRESULT doc_init_events(HTMLDocumentNode *doc)
4943 unsigned i;
4944 HRESULT hres;
4946 doc->event_vector = calloc(EVENTID_LAST, sizeof(BOOL));
4947 if(!doc->event_vector)
4948 return E_OUTOFMEMORY;
4950 init_nsevents(doc);
4952 for(i=0; i < EVENTID_LAST; i++) {
4953 if(event_info[i].flags & EVENT_HASDEFAULTHANDLERS) {
4954 hres = ensure_doc_nsevent_handler(doc, NULL, i);
4955 if(FAILED(hres))
4956 return hres;
4960 return S_OK;
4963 static inline EventTarget *impl_from_IEventTarget(IEventTarget *iface)
4965 return CONTAINING_RECORD(iface, EventTarget, IEventTarget_iface);
4968 DISPEX_IDISPATCH_IMPL(EventTarget, IEventTarget, impl_from_IEventTarget(iface)->dispex)
4970 static HRESULT WINAPI EventTarget_addEventListener(IEventTarget *iface, BSTR type,
4971 IDispatch *function, VARIANT_BOOL capture)
4973 EventTarget *This = impl_from_IEventTarget(iface);
4974 listener_type_t listener_type = capture ? LISTENER_TYPE_CAPTURE : LISTENER_TYPE_BUBBLE;
4975 listener_container_t *container;
4976 event_listener_t *listener;
4978 TRACE("(%p)->(%s %p %x)\n", This, debugstr_w(type), function, capture);
4980 if(!function)
4981 return S_OK;
4983 container = get_listener_container(This, type, TRUE);
4984 if(!container)
4985 return E_OUTOFMEMORY;
4987 /* check for duplicates */
4988 LIST_FOR_EACH_ENTRY(listener, &container->listeners, event_listener_t, entry) {
4989 if(listener->type == listener_type && listener->function == function)
4990 return S_OK;
4993 listener = malloc(sizeof(*listener));
4994 if(!listener)
4995 return E_OUTOFMEMORY;
4997 listener->type = listener_type;
4998 IDispatch_AddRef(listener->function = function);
4999 list_add_tail(&container->listeners, &listener->entry);
5000 return S_OK;
5003 static HRESULT WINAPI EventTarget_removeEventListener(IEventTarget *iface, BSTR type,
5004 IDispatch *listener, VARIANT_BOOL capture)
5006 EventTarget *This = impl_from_IEventTarget(iface);
5008 TRACE("(%p)->(%s %p %x)\n", This, debugstr_w(type), listener, capture);
5010 remove_event_listener(This, type, capture ? LISTENER_TYPE_CAPTURE : LISTENER_TYPE_BUBBLE, listener);
5011 return S_OK;
5014 static HRESULT WINAPI EventTarget_dispatchEvent(IEventTarget *iface, IDOMEvent *event_iface, VARIANT_BOOL *result)
5016 EventTarget *This = impl_from_IEventTarget(iface);
5017 DOMEvent *event = unsafe_impl_from_IDOMEvent(event_iface);
5019 TRACE("(%p)->(%p %p)\n", This, event, result);
5021 if(!event) {
5022 WARN("Invalid event\n");
5023 return E_INVALIDARG;
5026 return dispatch_event_object(This, event, DISPATCH_STANDARD, result);
5029 static HRESULT IEventTarget_addEventListener_hook(DispatchEx *dispex, WORD flags,
5030 DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
5032 /* If only two arguments were given, implicitly set capture to false */
5033 if((flags & DISPATCH_METHOD) && dp->cArgs == 2 && !dp->cNamedArgs) {
5034 VARIANT args[3];
5035 DISPPARAMS new_dp = {args, NULL, 3, 0};
5036 V_VT(args) = VT_BOOL;
5037 V_BOOL(args) = VARIANT_FALSE;
5038 args[1] = dp->rgvarg[0];
5039 args[2] = dp->rgvarg[1];
5041 TRACE("implicit capture\n");
5043 return dispex_call_builtin(dispex, DISPID_IEVENTTARGET_ADDEVENTLISTENER, &new_dp, res, ei, caller);
5046 return S_FALSE; /* fallback to default */
5049 static HRESULT IEventTarget_removeEventListener_hook(DispatchEx *dispex, WORD flags,
5050 DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
5052 /* If only two arguments were given, implicitly set capture to false */
5053 if((flags & DISPATCH_METHOD) && dp->cArgs == 2 && !dp->cNamedArgs) {
5054 VARIANT args[3];
5055 DISPPARAMS new_dp = {args, NULL, 3, 0};
5056 V_VT(args) = VT_BOOL;
5057 V_BOOL(args) = VARIANT_FALSE;
5058 args[1] = dp->rgvarg[0];
5059 args[2] = dp->rgvarg[1];
5061 TRACE("implicit capture\n");
5063 return dispex_call_builtin(dispex, DISPID_IEVENTTARGET_REMOVEEVENTLISTENER, &new_dp, res, ei, caller);
5066 return S_FALSE; /* fallback to default */
5069 static const IEventTargetVtbl EventTargetVtbl = {
5070 EventTarget_QueryInterface,
5071 EventTarget_AddRef,
5072 EventTarget_Release,
5073 EventTarget_GetTypeInfoCount,
5074 EventTarget_GetTypeInfo,
5075 EventTarget_GetIDsOfNames,
5076 EventTarget_Invoke,
5077 EventTarget_addEventListener,
5078 EventTarget_removeEventListener,
5079 EventTarget_dispatchEvent
5082 static EventTarget *unsafe_impl_from_IEventTarget(IEventTarget *iface)
5084 return iface && iface->lpVtbl == &EventTargetVtbl ? impl_from_IEventTarget(iface) : NULL;
5087 static HRESULT get_gecko_target(IEventTarget *target, nsIDOMEventTarget **ret)
5089 EventTarget *event_target = unsafe_impl_from_IEventTarget(target);
5090 const event_target_vtbl_t *vtbl;
5091 nsresult nsres;
5093 if(!event_target) {
5094 WARN("Not our IEventTarget implementation\n");
5095 return E_INVALIDARG;
5098 vtbl = (const event_target_vtbl_t*)dispex_get_vtbl(&event_target->dispex);
5099 nsres = nsISupports_QueryInterface(vtbl->get_gecko_target(&event_target->dispex),
5100 &IID_nsIDOMEventTarget, (void**)ret);
5101 assert(nsres == NS_OK);
5102 return S_OK;
5105 void *EventTarget_query_interface(EventTarget *event_target, REFIID riid)
5107 if(IsEqualGUID(riid, &IID_IEventTarget)) {
5108 if(use_event_quirks(event_target)) {
5109 WARN("IEventTarget queried, but not supported by in document mode\n");
5110 return NULL;
5112 return &event_target->IEventTarget_iface;
5115 return NULL;
5118 void EventTarget_init_dispex_info(dispex_data_t *dispex_info, compat_mode_t compat_mode)
5120 static const dispex_hook_t IEventTarget_hooks[] = {
5121 {DISPID_IEVENTTARGET_ADDEVENTLISTENER, IEventTarget_addEventListener_hook},
5122 {DISPID_IEVENTTARGET_REMOVEEVENTLISTENER, IEventTarget_removeEventListener_hook},
5123 {DISPID_UNKNOWN}
5126 if(compat_mode >= COMPAT_MODE_IE9)
5127 dispex_info_add_interface(dispex_info, IEventTarget_tid, IEventTarget_hooks);
5130 static int event_id_cmp(const void *key, const struct wine_rb_entry *entry)
5132 return wcscmp(key, WINE_RB_ENTRY_VALUE(entry, listener_container_t, entry)->type);
5135 void EventTarget_Init(EventTarget *event_target, dispex_static_data_t *dispex_data, compat_mode_t compat_mode)
5137 init_dispatch(&event_target->dispex, dispex_data, NULL, compat_mode);
5138 event_target->IEventTarget_iface.lpVtbl = &EventTargetVtbl;
5139 wine_rb_init(&event_target->handler_map, event_id_cmp);
5142 void init_event_target(EventTarget *event_target, dispex_static_data_t *dispex_data, HTMLInnerWindow *script_global)
5144 compat_mode_t compat_mode = script_global && script_global->doc ? script_global->doc->document_mode : COMPAT_MODE_NONE;
5145 init_dispatch(&event_target->dispex, dispex_data, script_global, compat_mode);
5146 event_target->IEventTarget_iface.lpVtbl = &EventTargetVtbl;
5147 wine_rb_init(&event_target->handler_map, event_id_cmp);
5150 void traverse_event_target(EventTarget *event_target, nsCycleCollectionTraversalCallback *cb)
5152 listener_container_t *iter;
5153 event_listener_t *listener;
5155 RB_FOR_EACH_ENTRY(iter, &event_target->handler_map, listener_container_t, entry)
5156 LIST_FOR_EACH_ENTRY(listener, &iter->listeners, event_listener_t, entry)
5157 if(listener->function)
5158 note_cc_edge((nsISupports*)listener->function, "EventTarget.listener", cb);
5161 void release_event_target(EventTarget *event_target)
5163 listener_container_t *iter, *iter2;
5165 WINE_RB_FOR_EACH_ENTRY_DESTRUCTOR(iter, iter2, &event_target->handler_map, listener_container_t, entry) {
5166 while(!list_empty(&iter->listeners)) {
5167 event_listener_t *listener = LIST_ENTRY(list_head(&iter->listeners), event_listener_t, entry);
5168 list_remove(&listener->entry);
5169 if(listener->function)
5170 IDispatch_Release(listener->function);
5171 free(listener);
5173 free(iter);
5175 rb_destroy(&event_target->handler_map, NULL, NULL);