Some notes for the loaded/total props for ProgressEvent: they are todo_wine for loadend initially because wine-gecko is never informed of OnProgress, but the last commit fixes this. It's placed last so that its effects can be shown. Also, if it wasn't deferred until OnDataAvailable, it would assume it's for uploading state, because it's OnStartRequest on gecko's XHR that changes the state...
-- v2: mshtml: Inform Gecko of progress done via OnProgress. mshtml: Implement ProgressEvent's total prop. mshtml: Implement ProgressEvent's loaded prop. mshtml: Implement ProgressEvent's lengthComputable prop. mshtml: Fix copy-paste mistake in test message. mshtml: Remove FIXME comment from MessageEvent in event_types. mshtml: Allocate Keyboard events via the types table. mshtml: Allocate Mouse events via the types table. mshtml: Allocate UI events via the types table. mshtml: Use a table to construct the different event types by their interface.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Avoids hardcoding as the amount of events grows to become more manageable, which will also be used for the existing hardcoded "special" events (UI, Mouse, Keyboard).
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 96 ++++++++++++++++++++++++++--------------- dlls/mshtml/nsiface.idl | 14 ++++++ 2 files changed, 76 insertions(+), 34 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 0f6525af86a..55fa6cf2302 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -2299,6 +2299,7 @@ static void DOMMessageEvent_destroy(DOMEvent *event) typedef struct { DOMEvent event; IDOMProgressEvent IDOMProgressEvent_iface; + nsIDOMProgressEvent *nsevent; } DOMProgressEvent;
static inline DOMProgressEvent *impl_from_IDOMProgressEvent(IDOMProgressEvent *iface) @@ -2412,6 +2413,12 @@ static void *DOMProgressEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
+static void DOMProgressEvent_destroy(DOMEvent *event) +{ + DOMProgressEvent *This = DOMProgressEvent_from_DOMEvent(event); + nsIDOMProgressEvent_Release(This->nsevent); +} + static const tid_t DOMEvent_iface_tids[] = { IDOMEvent_tid, 0 @@ -2504,58 +2511,79 @@ dispex_static_data_t DOMProgressEvent_dispex = { DOMProgressEvent_iface_tids };
-static BOOL check_event_iface(nsIDOMEvent *event, REFIID riid) +static void *event_ctor(unsigned size, void *(*query_interface)(DOMEvent*,REFIID), void (*destroy)(DOMEvent*)) { - nsISupports *iface; - nsresult nsres; + DOMEvent *event = heap_alloc_zero(size); + if(event) { + event->query_interface = query_interface; + event->destroy = destroy; + } + return event; +}
- nsres = nsIDOMEvent_QueryInterface(event, riid, (void**)&iface); - if(NS_FAILED(nsres)) - return FALSE; +static DOMEvent *custom_event_ctor(void *iface) +{ + DOMCustomEvent *custom_event = event_ctor(sizeof(DOMCustomEvent), DOMCustomEvent_query_interface, DOMCustomEvent_destroy); + if(!custom_event) return NULL; + custom_event->IDOMCustomEvent_iface.lpVtbl = &DOMCustomEventVtbl; + nsIDOMCustomEvent_Release(iface); + return &custom_event->event; +}
- nsISupports_Release(iface); - return TRUE; +static DOMEvent *progress_event_ctor(void *iface) +{ + DOMProgressEvent *progress_event = event_ctor(sizeof(DOMProgressEvent), DOMProgressEvent_query_interface, DOMProgressEvent_destroy); + if(!progress_event) return NULL; + progress_event->IDOMProgressEvent_iface.lpVtbl = &DOMProgressEventVtbl; + progress_event->nsevent = iface; + return &progress_event->event; }
static DOMEvent *alloc_event(nsIDOMEvent *nsevent, compat_mode_t compat_mode, eventid_t event_id) { + static const struct { + REFIID iid; + dispex_static_data_t *dispex_data; + DOMEvent *(*ctor)(void *iface); + compat_mode_t compat_mode; + } types_table[] = { + { &IID_nsIDOMCustomEvent, &DOMCustomEvent_dispex, custom_event_ctor }, + { &IID_nsIDOMProgressEvent, &DOMProgressEvent_dispex, progress_event_ctor, COMPAT_MODE_IE10 }, + }; dispex_static_data_t *dispex_data = &DOMEvent_dispex; DOMEvent *event = NULL; nsresult nsres; + unsigned i;
- if(check_event_iface(nsevent, &IID_nsIDOMCustomEvent)) { - DOMCustomEvent *custom_event = heap_alloc_zero(sizeof(*custom_event)); - if(!custom_event) - return NULL; - - custom_event->IDOMCustomEvent_iface.lpVtbl = &DOMCustomEventVtbl; - custom_event->event.query_interface = DOMCustomEvent_query_interface; - custom_event->event.destroy = DOMCustomEvent_destroy; - event = &custom_event->event; - dispex_data = &DOMCustomEvent_dispex; - }else if(event_id == EVENTID_MESSAGE) { - DOMMessageEvent *message_event = heap_alloc_zero(sizeof(*message_event)); + if(event_id == EVENTID_MESSAGE) { + DOMMessageEvent *message_event = event_ctor(sizeof(DOMMessageEvent), DOMMessageEvent_query_interface, DOMMessageEvent_destroy); if(!message_event) return NULL;
message_event->IDOMMessageEvent_iface.lpVtbl = &DOMMessageEventVtbl; - message_event->event.query_interface = DOMMessageEvent_query_interface; - message_event->event.destroy = DOMMessageEvent_destroy; event = &message_event->event; dispex_data = &DOMMessageEvent_dispex; - }else if(event_info[event_id].type == EVENT_TYPE_PROGRESS && compat_mode >= COMPAT_MODE_IE10) { - DOMProgressEvent *progress_event = heap_alloc_zero(sizeof(*progress_event)); - if(!progress_event) - return NULL; - - progress_event->IDOMProgressEvent_iface.lpVtbl = &DOMProgressEventVtbl; - progress_event->event.query_interface = DOMProgressEvent_query_interface; - event = &progress_event->event; - dispex_data = &DOMProgressEvent_dispex; }else { - event = heap_alloc_zero(sizeof(*event)); - if(!event) - return NULL; + for(i = 0; i < ARRAY_SIZE(types_table); i++) { + void *iface; + if(compat_mode < types_table[i].compat_mode) + continue; + nsres = nsIDOMEvent_QueryInterface(nsevent, types_table[i].iid, &iface); + if(NS_SUCCEEDED(nsres)) { + /* Transfer the iface ownership to the ctor on success */ + if(!(event = types_table[i].ctor(iface))) { + nsISupports_Release(iface); + return NULL; + } + dispex_data = types_table[i].dispex_data; + break; + } + } + if(i >= ARRAY_SIZE(types_table)) { + event = heap_alloc_zero(sizeof(*event)); + if(!event) + return NULL; + } }
event->IDOMEvent_iface.lpVtbl = &DOMEventVtbl; diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl index cad48f725c6..c4b479b16e3 100644 --- a/dlls/mshtml/nsiface.idl +++ b/dlls/mshtml/nsiface.idl @@ -3304,6 +3304,20 @@ interface nsIDOMKeyEvent : nsIDOMUIEvent nsresult GetKey(nsAString *aKey); }
+[ + object, + uuid(e0682338-4c3f-4d3a-9487-d7492ea76335), + local +] +interface nsIDOMProgressEvent : nsISupports +{ + nsresult GetLengthComputable(bool *aLengthComputable); + nsresult GetLoaded(uint64_t *aLoaded); + nsresult GetTotal(uint64_t *aTotal); + nsresult InitProgressEvent(const nsAString *typeArg, bool canBubbleArg, bool cancelableArg, + bool lengthComputableArg, uint64_t loadedArg, uint64_t totalArg); +} + [ object, uuid(5be16b03-36f9-4ca8-b2c5-0daadf3cd1b3),
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Instead of specially treating them.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 122 +++++++++++++++++++++++++--------------- dlls/mshtml/htmlevent.h | 2 - 2 files changed, 77 insertions(+), 47 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 55fa6cf2302..297acc69347 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -296,6 +296,17 @@ static void remove_event_listener(EventTarget *event_target, const WCHAR *type_n
static HRESULT get_gecko_target(IEventTarget*,nsIDOMEventTarget**);
+typedef struct { + DOMEvent event; + IDOMUIEvent IDOMUIEvent_iface; + nsIDOMUIEvent *nsevent; +} DOMUIEvent; + +static DOMUIEvent *DOMUIEvent_from_DOMEvent(DOMEvent *event) +{ + return CONTAINING_RECORD(event, DOMUIEvent, event); +} + typedef struct { DispatchEx dispex; IHTMLEventObj IHTMLEventObj_iface; @@ -609,12 +620,16 @@ static HRESULT WINAPI HTMLEventObj_get_x(IHTMLEventObj *iface, LONG *p)
TRACE("(%p)->(%p)\n", This, p);
- if(This->event && This->event->ui_event) { - nsresult nsres; + if(This->event) { + nsIDOMUIEvent *ui_event; + nsresult nsres = nsIDOMEvent_QueryInterface(This->event->nsevent, &IID_nsIDOMUIEvent, (void**)&ui_event);
- /* NOTE: pageX is not exactly right here. */ - nsres = nsIDOMUIEvent_GetPageX(This->event->ui_event, &x); - assert(nsres == NS_OK); + if(NS_SUCCEEDED(nsres)) { + /* NOTE: pageX is not exactly right here. */ + nsres = nsIDOMUIEvent_GetPageX(ui_event, &x); + assert(nsres == NS_OK); + nsIDOMUIEvent_Release(ui_event); + } }
*p = x; @@ -628,12 +643,16 @@ static HRESULT WINAPI HTMLEventObj_get_y(IHTMLEventObj *iface, LONG *p)
TRACE("(%p)->(%p)\n", This, p);
- if(This->event && This->event->ui_event) { - nsresult nsres; + if(This->event) { + nsIDOMUIEvent *ui_event; + nsresult nsres = nsIDOMEvent_QueryInterface(This->event->nsevent, &IID_nsIDOMUIEvent, (void**)&ui_event);
- /* NOTE: pageY is not exactly right here. */ - nsres = nsIDOMUIEvent_GetPageY(This->event->ui_event, &y); - assert(nsres == NS_OK); + if(NS_SUCCEEDED(nsres)) { + /* NOTE: pageY is not exactly right here. */ + nsres = nsIDOMUIEvent_GetPageY(ui_event, &y); + assert(nsres == NS_OK); + nsIDOMUIEvent_Release(ui_event); + } }
*p = y; @@ -832,8 +851,6 @@ static HRESULT WINAPI DOMEvent_QueryInterface(IDOMEvent *iface, REFIID riid, voi *ppv = &This->IDOMEvent_iface; else if(IsEqualGUID(&IID_IDOMEvent, riid)) *ppv = &This->IDOMEvent_iface; - else if(This->ui_event && IsEqualGUID(&IID_IDOMUIEvent, riid)) - *ppv = &This->IDOMUIEvent_iface; else if(This->mouse_event && IsEqualGUID(&IID_IDOMMouseEvent, riid)) *ppv = &This->IDOMMouseEvent_iface; else if(This->keyboard_event && IsEqualGUID(&IID_IDOMKeyboardEvent, riid)) @@ -870,8 +887,6 @@ static ULONG WINAPI DOMEvent_Release(IDOMEvent *iface) if(!ref) { if(This->destroy) This->destroy(This); - if(This->ui_event) - nsIDOMUIEvent_Release(This->ui_event); if(This->mouse_event) nsIDOMMouseEvent_Release(This->mouse_event); if(This->keyboard_event) @@ -1142,47 +1157,47 @@ static const IDOMEventVtbl DOMEventVtbl = { DOMEvent_get_srcElement };
-static inline DOMEvent *impl_from_IDOMUIEvent(IDOMUIEvent *iface) +static inline DOMUIEvent *impl_from_IDOMUIEvent(IDOMUIEvent *iface) { - return CONTAINING_RECORD(iface, DOMEvent, IDOMUIEvent_iface); + return CONTAINING_RECORD(iface, DOMUIEvent, IDOMUIEvent_iface); }
static HRESULT WINAPI DOMUIEvent_QueryInterface(IDOMUIEvent *iface, REFIID riid, void **ppv) { - DOMEvent *This = impl_from_IDOMUIEvent(iface); - return IDOMEvent_QueryInterface(&This->IDOMEvent_iface, riid, ppv); + DOMUIEvent *This = impl_from_IDOMUIEvent(iface); + return IDOMEvent_QueryInterface(&This->event.IDOMEvent_iface, riid, ppv); }
static ULONG WINAPI DOMUIEvent_AddRef(IDOMUIEvent *iface) { - DOMEvent *This = impl_from_IDOMUIEvent(iface); - return IDOMEvent_AddRef(&This->IDOMEvent_iface); + DOMUIEvent *This = impl_from_IDOMUIEvent(iface); + return IDOMEvent_AddRef(&This->event.IDOMEvent_iface); }
static ULONG WINAPI DOMUIEvent_Release(IDOMUIEvent *iface) { - DOMEvent *This = impl_from_IDOMUIEvent(iface); - return IDOMEvent_Release(&This->IDOMEvent_iface); + DOMUIEvent *This = impl_from_IDOMUIEvent(iface); + return IDOMEvent_Release(&This->event.IDOMEvent_iface); }
static HRESULT WINAPI DOMUIEvent_GetTypeInfoCount(IDOMUIEvent *iface, UINT *pctinfo) { - DOMEvent *This = impl_from_IDOMUIEvent(iface); - return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); + DOMUIEvent *This = impl_from_IDOMUIEvent(iface); + return IDispatchEx_GetTypeInfoCount(&This->event.dispex.IDispatchEx_iface, pctinfo); }
static HRESULT WINAPI DOMUIEvent_GetTypeInfo(IDOMUIEvent *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { - DOMEvent *This = impl_from_IDOMUIEvent(iface); - return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); + DOMUIEvent *This = impl_from_IDOMUIEvent(iface); + return IDispatchEx_GetTypeInfo(&This->event.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); }
static HRESULT WINAPI DOMUIEvent_GetIDsOfNames(IDOMUIEvent *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { - DOMEvent *This = impl_from_IDOMUIEvent(iface); - return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames, + DOMUIEvent *This = impl_from_IDOMUIEvent(iface); + return IDispatchEx_GetIDsOfNames(&This->event.dispex.IDispatchEx_iface, riid, rgszNames, cNames, lcid, rgDispId); }
@@ -1190,21 +1205,21 @@ static HRESULT WINAPI DOMUIEvent_Invoke(IDOMUIEvent *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { - DOMEvent *This = impl_from_IDOMUIEvent(iface); - return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, + DOMUIEvent *This = impl_from_IDOMUIEvent(iface); + return IDispatchEx_Invoke(&This->event.dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); }
static HRESULT WINAPI DOMUIEvent_get_view(IDOMUIEvent *iface, IHTMLWindow2 **p) { - DOMEvent *This = impl_from_IDOMUIEvent(iface); + DOMUIEvent *This = impl_from_IDOMUIEvent(iface); mozIDOMWindowProxy *moz_window; HTMLOuterWindow *view = NULL; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMUIEvent_GetView(This->ui_event, &moz_window); + nsres = nsIDOMUIEvent_GetView(This->nsevent, &moz_window); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1221,13 +1236,13 @@ static HRESULT WINAPI DOMUIEvent_get_view(IDOMUIEvent *iface, IHTMLWindow2 **p)
static HRESULT WINAPI DOMUIEvent_get_detail(IDOMUIEvent *iface, LONG *p) { - DOMEvent *This = impl_from_IDOMUIEvent(iface); + DOMUIEvent *This = impl_from_IDOMUIEvent(iface); LONG detail; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMUIEvent_GetDetail(This->ui_event, &detail); + nsres = nsIDOMUIEvent_GetDetail(This->nsevent, &detail); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1238,14 +1253,14 @@ static HRESULT WINAPI DOMUIEvent_get_detail(IDOMUIEvent *iface, LONG *p) static HRESULT WINAPI DOMUIEvent_initUIEvent(IDOMUIEvent *iface, BSTR type, VARIANT_BOOL can_bubble, VARIANT_BOOL cancelable, IHTMLWindow2 *view, LONG detail) { - DOMEvent *This = impl_from_IDOMUIEvent(iface); + DOMUIEvent *This = impl_from_IDOMUIEvent(iface); nsAString type_str; nsresult nsres; HRESULT hres;
TRACE("(%p)->(%s %x %x %p %lx)\n", This, debugstr_w(type), can_bubble, cancelable, view, detail);
- if(This->target) { + if(This->event.target) { TRACE("called on already dispatched event\n"); return S_OK; } @@ -1253,12 +1268,12 @@ static HRESULT WINAPI DOMUIEvent_initUIEvent(IDOMUIEvent *iface, BSTR type, VARI if(view) FIXME("view argument is not supported\n");
- hres = IDOMEvent_initEvent(&This->IDOMEvent_iface, type, can_bubble, cancelable); + hres = IDOMEvent_initEvent(&This->event.IDOMEvent_iface, type, can_bubble, cancelable); if(FAILED(hres)) return hres;
nsAString_InitDepend(&type_str, type); - nsres = nsIDOMUIEvent_InitUIEvent(This->ui_event, &type_str, !!can_bubble, !!cancelable, + nsres = nsIDOMUIEvent_InitUIEvent(This->nsevent, &type_str, !!can_bubble, !!cancelable, NULL /* FIXME */, detail); nsAString_Finish(&type_str); if(NS_FAILED(nsres)) { @@ -1282,6 +1297,20 @@ static const IDOMUIEventVtbl DOMUIEventVtbl = { DOMUIEvent_initUIEvent };
+static void *DOMUIEvent_query_interface(DOMEvent *event, REFIID riid) +{ + DOMUIEvent *This = DOMUIEvent_from_DOMEvent(event); + if(IsEqualGUID(&IID_IDOMUIEvent, riid)) + return &This->IDOMUIEvent_iface; + return NULL; +} + +static void DOMUIEvent_destroy(DOMEvent *event) +{ + DOMUIEvent *This = DOMUIEvent_from_DOMEvent(event); + nsIDOMUIEvent_Release(This->nsevent); +} + static inline DOMEvent *impl_from_IDOMMouseEvent(IDOMMouseEvent *iface) { return CONTAINING_RECORD(iface, DOMEvent, IDOMMouseEvent_iface); @@ -2521,6 +2550,15 @@ static void *event_ctor(unsigned size, void *(*query_interface)(DOMEvent*,REFIID return event; }
+static DOMEvent *ui_event_ctor(void *iface) +{ + DOMUIEvent *ui_event = event_ctor(sizeof(DOMUIEvent), DOMUIEvent_query_interface, DOMUIEvent_destroy); + if(!ui_event) return NULL; + ui_event->IDOMUIEvent_iface.lpVtbl = &DOMUIEventVtbl; + ui_event->nsevent = iface; + return &ui_event->event; +} + static DOMEvent *custom_event_ctor(void *iface) { DOMCustomEvent *custom_event = event_ctor(sizeof(DOMCustomEvent), DOMCustomEvent_query_interface, DOMCustomEvent_destroy); @@ -2547,6 +2585,7 @@ static DOMEvent *alloc_event(nsIDOMEvent *nsevent, compat_mode_t compat_mode, ev DOMEvent *(*ctor)(void *iface); compat_mode_t compat_mode; } types_table[] = { + { &IID_nsIDOMUIEvent, &DOMUIEvent_dispex, ui_event_ctor }, { &IID_nsIDOMCustomEvent, &DOMCustomEvent_dispex, custom_event_ctor }, { &IID_nsIDOMProgressEvent, &DOMProgressEvent_dispex, progress_event_ctor, COMPAT_MODE_IE10 }, }; @@ -2587,7 +2626,6 @@ static DOMEvent *alloc_event(nsIDOMEvent *nsevent, compat_mode_t compat_mode, ev }
event->IDOMEvent_iface.lpVtbl = &DOMEventVtbl; - event->IDOMUIEvent_iface.lpVtbl = &DOMUIEventVtbl; event->IDOMMouseEvent_iface.lpVtbl = &DOMMouseEventVtbl; event->IDOMKeyboardEvent_iface.lpVtbl = &DOMKeyboardEventVtbl; event->ref = 1; @@ -2605,12 +2643,6 @@ static DOMEvent *alloc_event(nsIDOMEvent *nsevent, compat_mode_t compat_mode, ev
event->time_stamp = get_time_stamp();
- nsres = nsIDOMEvent_QueryInterface(nsevent, &IID_nsIDOMUIEvent, (void**)&event->ui_event); - if(NS_SUCCEEDED(nsres)) - dispex_data = &DOMUIEvent_dispex; - else - event->ui_event = NULL; - nsres = nsIDOMEvent_QueryInterface(nsevent, &IID_nsIDOMMouseEvent, (void**)&event->mouse_event); if(NS_SUCCEEDED(nsres)) dispex_data = &DOMMouseEvent_dispex; diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index 615387cc252..26c6d353011 100644 --- a/dlls/mshtml/htmlevent.h +++ b/dlls/mshtml/htmlevent.h @@ -67,7 +67,6 @@ typedef enum { typedef struct DOMEvent { DispatchEx dispex; IDOMEvent IDOMEvent_iface; - IDOMUIEvent IDOMUIEvent_iface; IDOMMouseEvent IDOMMouseEvent_iface; IDOMKeyboardEvent IDOMKeyboardEvent_iface;
@@ -76,7 +75,6 @@ typedef struct DOMEvent { void (*destroy)(struct DOMEvent*);
nsIDOMEvent *nsevent; - nsIDOMUIEvent *ui_event; nsIDOMMouseEvent *mouse_event; nsIDOMKeyEvent *keyboard_event;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Instead of specially treating them.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 287 ++++++++++++++++++++++++++-------------- dlls/mshtml/htmlevent.h | 2 - 2 files changed, 184 insertions(+), 105 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 297acc69347..f61c3db44e2 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -419,12 +419,16 @@ static HRESULT WINAPI HTMLEventObj_get_srcElement(IHTMLEventObj *iface, IHTMLEle static HRESULT WINAPI HTMLEventObj_get_altKey(IHTMLEventObj *iface, VARIANT_BOOL *p) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); + IDOMMouseEvent *mouse_event; cpp_bool ret = FALSE;
TRACE("(%p)->(%p)\n", This, p);
- if(This->event && This->event->mouse_event) - return IDOMMouseEvent_get_altKey(&This->event->IDOMMouseEvent_iface, p); + if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) { + HRESULT hres = IDOMMouseEvent_get_altKey(mouse_event, p); + IDOMMouseEvent_Release(mouse_event); + return hres; + }
if(This->event && This->event->keyboard_event) return IDOMKeyboardEvent_get_altKey(&This->event->IDOMKeyboardEvent_iface, p); @@ -436,12 +440,16 @@ static HRESULT WINAPI HTMLEventObj_get_altKey(IHTMLEventObj *iface, VARIANT_BOOL static HRESULT WINAPI HTMLEventObj_get_ctrlKey(IHTMLEventObj *iface, VARIANT_BOOL *p) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); + IDOMMouseEvent *mouse_event; cpp_bool ret = FALSE;
TRACE("(%p)->(%p)\n", This, p);
- if(This->event && This->event->mouse_event) - return IDOMMouseEvent_get_ctrlKey(&This->event->IDOMMouseEvent_iface, p); + if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) { + HRESULT hres = IDOMMouseEvent_get_ctrlKey(mouse_event, p); + IDOMMouseEvent_Release(mouse_event); + return hres; + }
if(This->event && This->event->keyboard_event) return IDOMKeyboardEvent_get_ctrlKey(&This->event->IDOMKeyboardEvent_iface, p); @@ -453,12 +461,16 @@ static HRESULT WINAPI HTMLEventObj_get_ctrlKey(IHTMLEventObj *iface, VARIANT_BOO static HRESULT WINAPI HTMLEventObj_get_shiftKey(IHTMLEventObj *iface, VARIANT_BOOL *p) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); + IDOMMouseEvent *mouse_event; cpp_bool ret = FALSE;
TRACE("(%p)->(%p)\n", This, p);
- if(This->event && This->event->mouse_event) - return IDOMMouseEvent_get_shiftKey(&This->event->IDOMMouseEvent_iface, p); + if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) { + HRESULT hres = IDOMMouseEvent_get_shiftKey(mouse_event, p); + IDOMMouseEvent_Release(mouse_event); + return hres; + }
if(This->event && This->event->keyboard_event) return IDOMKeyboardEvent_get_shiftKey(&This->event->IDOMKeyboardEvent_iface, p); @@ -518,11 +530,15 @@ static HRESULT WINAPI HTMLEventObj_get_cancelBubble(IHTMLEventObj *iface, VARIAN static HRESULT WINAPI HTMLEventObj_get_fromElement(IHTMLEventObj *iface, IHTMLElement **p) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); + IDOMMouseEvent *mouse_event;
TRACE("(%p)->(%p)\n", This, p);
- if(This->event && This->event->mouse_event) - return IDOMMouseEvent_get_fromElement(&This->event->IDOMMouseEvent_iface, p); + if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) { + HRESULT hres = IDOMMouseEvent_get_fromElement(mouse_event, p); + IDOMMouseEvent_Release(mouse_event); + return hres; + }
*p = NULL; return S_OK; @@ -531,11 +547,15 @@ static HRESULT WINAPI HTMLEventObj_get_fromElement(IHTMLEventObj *iface, IHTMLEl static HRESULT WINAPI HTMLEventObj_get_toElement(IHTMLEventObj *iface, IHTMLElement **p) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); + IDOMMouseEvent *mouse_event;
TRACE("(%p)->(%p)\n", This, p);
- if(This->event && This->event->mouse_event) - return IDOMMouseEvent_get_toElement(&This->event->IDOMMouseEvent_iface, p); + if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) { + HRESULT hres = IDOMMouseEvent_get_toElement(mouse_event, p); + IDOMMouseEvent_Release(mouse_event); + return hres; + }
*p = NULL; return S_OK; @@ -564,13 +584,14 @@ static HRESULT WINAPI HTMLEventObj_get_keyCode(IHTMLEventObj *iface, LONG *p) static HRESULT WINAPI HTMLEventObj_get_button(IHTMLEventObj *iface, LONG *p) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); + IDOMMouseEvent *mouse_event; USHORT button = 0;
TRACE("(%p)->(%p)\n", This, p);
- if(This->event && This->event->mouse_event) { - HRESULT hres; - hres = IDOMMouseEvent_get_button(&This->event->IDOMMouseEvent_iface, &button); + if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) { + HRESULT hres = IDOMMouseEvent_get_button(mouse_event, &button); + IDOMMouseEvent_Release(mouse_event); if(FAILED(hres)) return hres; } @@ -662,11 +683,15 @@ static HRESULT WINAPI HTMLEventObj_get_y(IHTMLEventObj *iface, LONG *p) static HRESULT WINAPI HTMLEventObj_get_clientX(IHTMLEventObj *iface, LONG *p) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); + IDOMMouseEvent *mouse_event;
TRACE("(%p)->(%p)\n", This, p);
- if(This->event && This->event->mouse_event) - return IDOMMouseEvent_get_clientX(&This->event->IDOMMouseEvent_iface, p); + if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) { + HRESULT hres = IDOMMouseEvent_get_clientX(mouse_event, p); + IDOMMouseEvent_Release(mouse_event); + return hres; + }
*p = 0; return S_OK; @@ -675,11 +700,15 @@ static HRESULT WINAPI HTMLEventObj_get_clientX(IHTMLEventObj *iface, LONG *p) static HRESULT WINAPI HTMLEventObj_get_clientY(IHTMLEventObj *iface, LONG *p) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); + IDOMMouseEvent *mouse_event;
TRACE("(%p)->(%p)\n", This, p);
- if(This->event && This->event->mouse_event) - return IDOMMouseEvent_get_clientY(&This->event->IDOMMouseEvent_iface, p); + if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) { + HRESULT hres = IDOMMouseEvent_get_clientY(mouse_event, p); + IDOMMouseEvent_Release(mouse_event); + return hres; + }
*p = 0; return S_OK; @@ -688,11 +717,15 @@ static HRESULT WINAPI HTMLEventObj_get_clientY(IHTMLEventObj *iface, LONG *p) static HRESULT WINAPI HTMLEventObj_get_offsetX(IHTMLEventObj *iface, LONG *p) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); + IDOMMouseEvent *mouse_event;
TRACE("(%p)->(%p)\n", This, p);
- if(This->event && This->event->mouse_event) - return IDOMMouseEvent_get_offsetX(&This->event->IDOMMouseEvent_iface, p); + if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) { + HRESULT hres = IDOMMouseEvent_get_offsetX(mouse_event, p); + IDOMMouseEvent_Release(mouse_event); + return hres; + }
*p = 0; return S_OK; @@ -701,11 +734,15 @@ static HRESULT WINAPI HTMLEventObj_get_offsetX(IHTMLEventObj *iface, LONG *p) static HRESULT WINAPI HTMLEventObj_get_offsetY(IHTMLEventObj *iface, LONG *p) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); + IDOMMouseEvent *mouse_event;
TRACE("(%p)->(%p)\n", This, p);
- if(This->event && This->event->mouse_event) - return IDOMMouseEvent_get_offsetY(&This->event->IDOMMouseEvent_iface, p); + if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) { + HRESULT hres = IDOMMouseEvent_get_offsetY(mouse_event, p); + IDOMMouseEvent_Release(mouse_event); + return hres; + }
*p = 0; return S_OK; @@ -714,11 +751,15 @@ static HRESULT WINAPI HTMLEventObj_get_offsetY(IHTMLEventObj *iface, LONG *p) static HRESULT WINAPI HTMLEventObj_get_screenX(IHTMLEventObj *iface, LONG *p) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); + IDOMMouseEvent *mouse_event;
TRACE("(%p)->(%p)\n", This, p);
- if(This->event && This->event->mouse_event) - return IDOMMouseEvent_get_screenX(&This->event->IDOMMouseEvent_iface, p); + if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) { + HRESULT hres = IDOMMouseEvent_get_screenX(mouse_event, p); + IDOMMouseEvent_Release(mouse_event); + return hres; + }
*p = 0; return S_OK; @@ -727,11 +768,15 @@ static HRESULT WINAPI HTMLEventObj_get_screenX(IHTMLEventObj *iface, LONG *p) static HRESULT WINAPI HTMLEventObj_get_screenY(IHTMLEventObj *iface, LONG *p) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); + IDOMMouseEvent *mouse_event;
TRACE("(%p)->(%p)\n", This, p);
- if(This->event && This->event->mouse_event) - return IDOMMouseEvent_get_screenY(&This->event->IDOMMouseEvent_iface, p); + if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMMouseEvent, (void**)&mouse_event))) { + HRESULT hres = IDOMMouseEvent_get_screenY(mouse_event, p); + IDOMMouseEvent_Release(mouse_event); + return hres; + }
*p = 0; return S_OK; @@ -851,8 +896,6 @@ static HRESULT WINAPI DOMEvent_QueryInterface(IDOMEvent *iface, REFIID riid, voi *ppv = &This->IDOMEvent_iface; else if(IsEqualGUID(&IID_IDOMEvent, riid)) *ppv = &This->IDOMEvent_iface; - else if(This->mouse_event && IsEqualGUID(&IID_IDOMMouseEvent, riid)) - *ppv = &This->IDOMMouseEvent_iface; else if(This->keyboard_event && IsEqualGUID(&IID_IDOMKeyboardEvent, riid)) *ppv = &This->IDOMKeyboardEvent_iface; else if(dispex_query_interface(&This->dispex, riid, ppv)) @@ -887,8 +930,6 @@ static ULONG WINAPI DOMEvent_Release(IDOMEvent *iface) if(!ref) { if(This->destroy) This->destroy(This); - if(This->mouse_event) - nsIDOMMouseEvent_Release(This->mouse_event); if(This->keyboard_event) nsIDOMKeyEvent_Release(This->keyboard_event); if(This->target) @@ -1311,47 +1352,53 @@ static void DOMUIEvent_destroy(DOMEvent *event) nsIDOMUIEvent_Release(This->nsevent); }
-static inline DOMEvent *impl_from_IDOMMouseEvent(IDOMMouseEvent *iface) +typedef struct { + DOMUIEvent ui_event; + IDOMMouseEvent IDOMMouseEvent_iface; + nsIDOMMouseEvent *nsevent; +} DOMMouseEvent; + +static inline DOMMouseEvent *impl_from_IDOMMouseEvent(IDOMMouseEvent *iface) { - return CONTAINING_RECORD(iface, DOMEvent, IDOMMouseEvent_iface); + return CONTAINING_RECORD(iface, DOMMouseEvent, IDOMMouseEvent_iface); }
static HRESULT WINAPI DOMMouseEvent_QueryInterface(IDOMMouseEvent *iface, REFIID riid, void **ppv) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); - return IDOMEvent_QueryInterface(&This->IDOMEvent_iface, riid, ppv); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); + return IDOMEvent_QueryInterface(&This->ui_event.event.IDOMEvent_iface, riid, ppv); }
static ULONG WINAPI DOMMouseEvent_AddRef(IDOMMouseEvent *iface) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); - return IDOMEvent_AddRef(&This->IDOMEvent_iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); + return IDOMEvent_AddRef(&This->ui_event.event.IDOMEvent_iface); }
static ULONG WINAPI DOMMouseEvent_Release(IDOMMouseEvent *iface) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); - return IDOMEvent_Release(&This->IDOMEvent_iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); + return IDOMEvent_Release(&This->ui_event.event.IDOMEvent_iface); }
static HRESULT WINAPI DOMMouseEvent_GetTypeInfoCount(IDOMMouseEvent *iface, UINT *pctinfo) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); - return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); + return IDispatchEx_GetTypeInfoCount(&This->ui_event.event.dispex.IDispatchEx_iface, pctinfo); }
static HRESULT WINAPI DOMMouseEvent_GetTypeInfo(IDOMMouseEvent *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); - return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); + return IDispatchEx_GetTypeInfo(&This->ui_event.event.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); }
static HRESULT WINAPI DOMMouseEvent_GetIDsOfNames(IDOMMouseEvent *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); - return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames, + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); + return IDispatchEx_GetIDsOfNames(&This->ui_event.event.dispex.IDispatchEx_iface, riid, rgszNames, cNames, lcid, rgDispId); }
@@ -1359,20 +1406,20 @@ static HRESULT WINAPI DOMMouseEvent_Invoke(IDOMMouseEvent *iface, DISPID dispIdM REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); - return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); + return IDispatchEx_Invoke(&This->ui_event.event.dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); }
static HRESULT WINAPI DOMMouseEvent_get_screenX(IDOMMouseEvent *iface, LONG *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); LONG screen_x; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMMouseEvent_GetScreenX(This->mouse_event, &screen_x); + nsres = nsIDOMMouseEvent_GetScreenX(This->nsevent, &screen_x); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1382,13 +1429,13 @@ static HRESULT WINAPI DOMMouseEvent_get_screenX(IDOMMouseEvent *iface, LONG *p)
static HRESULT WINAPI DOMMouseEvent_get_screenY(IDOMMouseEvent *iface, LONG *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); LONG screen_y; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMMouseEvent_GetScreenY(This->mouse_event, &screen_y); + nsres = nsIDOMMouseEvent_GetScreenY(This->nsevent, &screen_y); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1398,13 +1445,13 @@ static HRESULT WINAPI DOMMouseEvent_get_screenY(IDOMMouseEvent *iface, LONG *p)
static HRESULT WINAPI DOMMouseEvent_get_clientX(IDOMMouseEvent *iface, LONG *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); LONG client_x; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMMouseEvent_GetClientX(This->mouse_event, &client_x); + nsres = nsIDOMMouseEvent_GetClientX(This->nsevent, &client_x); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1414,13 +1461,13 @@ static HRESULT WINAPI DOMMouseEvent_get_clientX(IDOMMouseEvent *iface, LONG *p)
static HRESULT WINAPI DOMMouseEvent_get_clientY(IDOMMouseEvent *iface, LONG *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); LONG client_y; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMMouseEvent_GetClientY(This->mouse_event, &client_y); + nsres = nsIDOMMouseEvent_GetClientY(This->nsevent, &client_y); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1430,13 +1477,13 @@ static HRESULT WINAPI DOMMouseEvent_get_clientY(IDOMMouseEvent *iface, LONG *p)
static HRESULT WINAPI DOMMouseEvent_get_ctrlKey(IDOMMouseEvent *iface, VARIANT_BOOL *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); cpp_bool r; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMMouseEvent_GetCtrlKey(This->mouse_event, &r); + nsres = nsIDOMMouseEvent_GetCtrlKey(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1446,13 +1493,13 @@ static HRESULT WINAPI DOMMouseEvent_get_ctrlKey(IDOMMouseEvent *iface, VARIANT_B
static HRESULT WINAPI DOMMouseEvent_get_shiftKey(IDOMMouseEvent *iface, VARIANT_BOOL *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); cpp_bool r; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMMouseEvent_GetShiftKey(This->mouse_event, &r); + nsres = nsIDOMMouseEvent_GetShiftKey(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1462,13 +1509,13 @@ static HRESULT WINAPI DOMMouseEvent_get_shiftKey(IDOMMouseEvent *iface, VARIANT_
static HRESULT WINAPI DOMMouseEvent_get_altKey(IDOMMouseEvent *iface, VARIANT_BOOL *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); cpp_bool r; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMMouseEvent_GetAltKey(This->mouse_event, &r); + nsres = nsIDOMMouseEvent_GetAltKey(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1478,13 +1525,13 @@ static HRESULT WINAPI DOMMouseEvent_get_altKey(IDOMMouseEvent *iface, VARIANT_BO
static HRESULT WINAPI DOMMouseEvent_get_metaKey(IDOMMouseEvent *iface, VARIANT_BOOL *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); cpp_bool r; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMMouseEvent_GetMetaKey(This->mouse_event, &r); + nsres = nsIDOMMouseEvent_GetMetaKey(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1494,13 +1541,13 @@ static HRESULT WINAPI DOMMouseEvent_get_metaKey(IDOMMouseEvent *iface, VARIANT_B
static HRESULT WINAPI DOMMouseEvent_get_button(IDOMMouseEvent *iface, USHORT *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); INT16 r; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMMouseEvent_GetButton(This->mouse_event, &r); + nsres = nsIDOMMouseEvent_GetButton(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1510,7 +1557,7 @@ static HRESULT WINAPI DOMMouseEvent_get_button(IDOMMouseEvent *iface, USHORT *p)
static HRESULT WINAPI DOMMouseEvent_get_relatedTarget(IDOMMouseEvent *iface, IEventTarget **p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); nsIDOMEventTarget *related_target; nsIDOMNode *target_node; HTMLDOMNode *node; @@ -1519,7 +1566,7 @@ static HRESULT WINAPI DOMMouseEvent_get_relatedTarget(IDOMMouseEvent *iface, IEv
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMMouseEvent_GetRelatedTarget(This->mouse_event, &related_target); + nsres = nsIDOMMouseEvent_GetRelatedTarget(This->nsevent, &related_target); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1550,7 +1597,7 @@ static HRESULT WINAPI DOMMouseEvent_initMouseEvent(IDOMMouseEvent *iface, BSTR t VARIANT_BOOL alt_key, VARIANT_BOOL shift_key, VARIANT_BOOL meta_key, USHORT button, IEventTarget *related_target) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); nsIDOMEventTarget *nstarget = NULL; nsAString type_str; nsresult nsres; @@ -1560,7 +1607,7 @@ static HRESULT WINAPI DOMMouseEvent_initMouseEvent(IDOMMouseEvent *iface, BSTR t can_bubble, cancelable, view, detail, screen_x, screen_y, client_x, client_y, ctrl_key, alt_key, shift_key, meta_key, button, related_target);
- if(This->target) { + if(This->ui_event.event.target) { TRACE("called on already dispatched event\n"); return S_OK; } @@ -1574,10 +1621,10 @@ static HRESULT WINAPI DOMMouseEvent_initMouseEvent(IDOMMouseEvent *iface, BSTR t return hres; }
- hres = IDOMEvent_initEvent(&This->IDOMEvent_iface, type, can_bubble, cancelable); + hres = IDOMEvent_initEvent(&This->ui_event.event.IDOMEvent_iface, type, can_bubble, cancelable); if(SUCCEEDED(hres)) { nsAString_InitDepend(&type_str, type); - nsres = nsIDOMMouseEvent_InitMouseEvent(This->mouse_event, &type_str, can_bubble, cancelable, + nsres = nsIDOMMouseEvent_InitMouseEvent(This->nsevent, &type_str, can_bubble, cancelable, NULL /* FIXME */, detail, screen_x, screen_y, client_x, client_y, !!ctrl_key, !!alt_key, !!shift_key, !!meta_key, button, nstarget); @@ -1596,20 +1643,20 @@ static HRESULT WINAPI DOMMouseEvent_initMouseEvent(IDOMMouseEvent *iface, BSTR t static HRESULT WINAPI DOMMouseEvent_getModifierState(IDOMMouseEvent *iface, BSTR key, VARIANT_BOOL *activated) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); FIXME("(%p)->(%s %p)\n", This, debugstr_w(key), activated); return E_NOTIMPL; }
static HRESULT WINAPI DOMMouseEvent_get_buttons(IDOMMouseEvent *iface, USHORT *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); UINT16 r; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMMouseEvent_GetButtons(This->mouse_event, &r); + nsres = nsIDOMMouseEvent_GetButtons(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1619,17 +1666,18 @@ static HRESULT WINAPI DOMMouseEvent_get_buttons(IDOMMouseEvent *iface, USHORT *p
static HRESULT WINAPI DOMMouseEvent_get_fromElement(IDOMMouseEvent *iface, IHTMLElement **p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); + eventid_t event_id = This->ui_event.event.event_id; IEventTarget *related_target = NULL;
TRACE("(%p)->(%p)\n", This, p);
- if(This->event_id != EVENTID_LAST) { + if(event_id != EVENTID_LAST) { HRESULT hres = S_OK; - if(event_info[This->event_id].flags & EVENT_MOUSE_FROM_RELATED) + if(event_info[event_id].flags & EVENT_MOUSE_FROM_RELATED) hres = IDOMMouseEvent_get_relatedTarget(&This->IDOMMouseEvent_iface, &related_target); - else if(event_info[This->event_id].flags & EVENT_MOUSE_TO_RELATED) - hres = IDOMEvent_get_target(&This->IDOMEvent_iface, &related_target); + else if(event_info[event_id].flags & EVENT_MOUSE_TO_RELATED) + hres = IDOMEvent_get_target(&This->ui_event.event.IDOMEvent_iface, &related_target); if(FAILED(hres)) return hres; } @@ -1645,17 +1693,18 @@ static HRESULT WINAPI DOMMouseEvent_get_fromElement(IDOMMouseEvent *iface, IHTML
static HRESULT WINAPI DOMMouseEvent_get_toElement(IDOMMouseEvent *iface, IHTMLElement **p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); + eventid_t event_id = This->ui_event.event.event_id; IEventTarget *related_target = NULL;
TRACE("(%p)->(%p)\n", This, p);
- if(This->event_id != EVENTID_LAST) { + if(event_id != EVENTID_LAST) { HRESULT hres = S_OK; - if(event_info[This->event_id].flags & EVENT_MOUSE_TO_RELATED) + if(event_info[event_id].flags & EVENT_MOUSE_TO_RELATED) hres = IDOMMouseEvent_get_relatedTarget(&This->IDOMMouseEvent_iface, &related_target); - else if(event_info[This->event_id].flags & EVENT_MOUSE_FROM_RELATED) - hres = IDOMEvent_get_target(&This->IDOMEvent_iface, &related_target); + else if(event_info[event_id].flags & EVENT_MOUSE_FROM_RELATED) + hres = IDOMEvent_get_target(&This->ui_event.event.IDOMEvent_iface, &related_target); if(FAILED(hres)) return hres; } @@ -1671,21 +1720,21 @@ static HRESULT WINAPI DOMMouseEvent_get_toElement(IDOMMouseEvent *iface, IHTMLEl
static HRESULT WINAPI DOMMouseEvent_get_x(IDOMMouseEvent *iface, LONG *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); FIXME("(%p)->(%p)\n", This, p); return E_NOTIMPL; }
static HRESULT WINAPI DOMMouseEvent_get_y(IDOMMouseEvent *iface, LONG *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); FIXME("(%p)->(%p)\n", This, p); return E_NOTIMPL; }
static HRESULT WINAPI DOMMouseEvent_get_offsetX(IDOMMouseEvent *iface, LONG *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
FIXME("(%p)->(%p) returning 0\n", This, p);
@@ -1695,7 +1744,7 @@ static HRESULT WINAPI DOMMouseEvent_get_offsetX(IDOMMouseEvent *iface, LONG *p)
static HRESULT WINAPI DOMMouseEvent_get_offsetY(IDOMMouseEvent *iface, LONG *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface);
FIXME("(%p)->(%p) returning 0\n", This, p);
@@ -1705,13 +1754,13 @@ static HRESULT WINAPI DOMMouseEvent_get_offsetY(IDOMMouseEvent *iface, LONG *p)
static HRESULT WINAPI DOMMouseEvent_get_pageX(IDOMMouseEvent *iface, LONG *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); LONG r; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMMouseEvent_GetPageX(This->mouse_event, &r); + nsres = nsIDOMMouseEvent_GetPageX(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1721,13 +1770,13 @@ static HRESULT WINAPI DOMMouseEvent_get_pageX(IDOMMouseEvent *iface, LONG *p)
static HRESULT WINAPI DOMMouseEvent_get_pageY(IDOMMouseEvent *iface, LONG *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); LONG r; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMMouseEvent_GetPageY(This->mouse_event, &r); + nsres = nsIDOMMouseEvent_GetPageY(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1737,13 +1786,13 @@ static HRESULT WINAPI DOMMouseEvent_get_pageY(IDOMMouseEvent *iface, LONG *p)
static HRESULT WINAPI DOMMouseEvent_get_layerX(IDOMMouseEvent *iface, LONG *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); nsresult nsres; LONG r;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMMouseEvent_GetLayerX(This->mouse_event, &r); + nsres = nsIDOMMouseEvent_GetLayerX(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1753,13 +1802,13 @@ static HRESULT WINAPI DOMMouseEvent_get_layerX(IDOMMouseEvent *iface, LONG *p)
static HRESULT WINAPI DOMMouseEvent_get_layerY(IDOMMouseEvent *iface, LONG *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); nsresult nsres; LONG r;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMMouseEvent_GetLayerY(This->mouse_event, &r); + nsres = nsIDOMMouseEvent_GetLayerY(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1769,13 +1818,13 @@ static HRESULT WINAPI DOMMouseEvent_get_layerY(IDOMMouseEvent *iface, LONG *p)
static HRESULT WINAPI DOMMouseEvent_get_which(IDOMMouseEvent *iface, USHORT *p) { - DOMEvent *This = impl_from_IDOMMouseEvent(iface); + DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); UINT32 r; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMMouseEvent_GetWhich(This->mouse_event, &r); + nsres = nsIDOMMouseEvent_GetWhich(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1817,6 +1866,28 @@ static const IDOMMouseEventVtbl DOMMouseEventVtbl = { DOMMouseEvent_get_which };
+static DOMMouseEvent *DOMMouseEvent_from_DOMEvent(DOMEvent *event) +{ + return CONTAINING_RECORD(event, DOMMouseEvent, ui_event.event); +} + +static void *DOMMouseEvent_query_interface(DOMEvent *event, REFIID riid) +{ + DOMMouseEvent *This = DOMMouseEvent_from_DOMEvent(event); + if(IsEqualGUID(&IID_IDOMMouseEvent, riid)) + return &This->IDOMMouseEvent_iface; + if(IsEqualGUID(&IID_IDOMUIEvent, riid)) + return &This->ui_event.IDOMUIEvent_iface; + return NULL; +} + +static void DOMMouseEvent_destroy(DOMEvent *event) +{ + DOMMouseEvent *This = DOMMouseEvent_from_DOMEvent(event); + DOMUIEvent_destroy(&This->ui_event.event); + nsIDOMMouseEvent_Release(This->nsevent); +} + static inline DOMEvent *impl_from_IDOMKeyboardEvent(IDOMKeyboardEvent *iface) { return CONTAINING_RECORD(iface, DOMEvent, IDOMKeyboardEvent_iface); @@ -2550,6 +2621,12 @@ static void *event_ctor(unsigned size, void *(*query_interface)(DOMEvent*,REFIID return event; }
+static void fill_parent_ui_event(void *iface, DOMUIEvent *ui_event) +{ + ui_event->IDOMUIEvent_iface.lpVtbl = &DOMUIEventVtbl; + nsISupports_QueryInterface(iface, &IID_nsIDOMUIEvent, (void**)&ui_event->nsevent); +} + static DOMEvent *ui_event_ctor(void *iface) { DOMUIEvent *ui_event = event_ctor(sizeof(DOMUIEvent), DOMUIEvent_query_interface, DOMUIEvent_destroy); @@ -2559,6 +2636,16 @@ static DOMEvent *ui_event_ctor(void *iface) return &ui_event->event; }
+static DOMEvent *mouse_event_ctor(void *iface) +{ + DOMMouseEvent *mouse_event = event_ctor(sizeof(DOMMouseEvent), DOMMouseEvent_query_interface, DOMMouseEvent_destroy); + if(!mouse_event) return NULL; + mouse_event->IDOMMouseEvent_iface.lpVtbl = &DOMMouseEventVtbl; + mouse_event->nsevent = iface; + fill_parent_ui_event(iface, &mouse_event->ui_event); + return &mouse_event->ui_event.event; +} + static DOMEvent *custom_event_ctor(void *iface) { DOMCustomEvent *custom_event = event_ctor(sizeof(DOMCustomEvent), DOMCustomEvent_query_interface, DOMCustomEvent_destroy); @@ -2585,6 +2672,7 @@ static DOMEvent *alloc_event(nsIDOMEvent *nsevent, compat_mode_t compat_mode, ev DOMEvent *(*ctor)(void *iface); compat_mode_t compat_mode; } types_table[] = { + { &IID_nsIDOMMouseEvent, &DOMMouseEvent_dispex, mouse_event_ctor }, { &IID_nsIDOMUIEvent, &DOMUIEvent_dispex, ui_event_ctor }, { &IID_nsIDOMCustomEvent, &DOMCustomEvent_dispex, custom_event_ctor }, { &IID_nsIDOMProgressEvent, &DOMProgressEvent_dispex, progress_event_ctor, COMPAT_MODE_IE10 }, @@ -2626,7 +2714,6 @@ static DOMEvent *alloc_event(nsIDOMEvent *nsevent, compat_mode_t compat_mode, ev }
event->IDOMEvent_iface.lpVtbl = &DOMEventVtbl; - event->IDOMMouseEvent_iface.lpVtbl = &DOMMouseEventVtbl; event->IDOMKeyboardEvent_iface.lpVtbl = &DOMKeyboardEventVtbl; event->ref = 1; event->event_id = event_id; @@ -2643,12 +2730,6 @@ static DOMEvent *alloc_event(nsIDOMEvent *nsevent, compat_mode_t compat_mode, ev
event->time_stamp = get_time_stamp();
- nsres = nsIDOMEvent_QueryInterface(nsevent, &IID_nsIDOMMouseEvent, (void**)&event->mouse_event); - if(NS_SUCCEEDED(nsres)) - dispex_data = &DOMMouseEvent_dispex; - else - event->mouse_event = NULL; - nsres = nsIDOMEvent_QueryInterface(nsevent, &IID_nsIDOMKeyEvent, (void**)&event->keyboard_event); if(NS_SUCCEEDED(nsres)) dispex_data = &DOMKeyboardEvent_dispex; diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index 26c6d353011..207c0a7aaab 100644 --- a/dlls/mshtml/htmlevent.h +++ b/dlls/mshtml/htmlevent.h @@ -67,7 +67,6 @@ typedef enum { typedef struct DOMEvent { DispatchEx dispex; IDOMEvent IDOMEvent_iface; - IDOMMouseEvent IDOMMouseEvent_iface; IDOMKeyboardEvent IDOMKeyboardEvent_iface;
LONG ref; @@ -75,7 +74,6 @@ typedef struct DOMEvent { void (*destroy)(struct DOMEvent*);
nsIDOMEvent *nsevent; - nsIDOMMouseEvent *mouse_event; nsIDOMKeyEvent *keyboard_event;
eventid_t event_id;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Instead of specially treating them.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 162 +++++++++++++++++++++++++--------------- dlls/mshtml/htmlevent.h | 2 - 2 files changed, 103 insertions(+), 61 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index f61c3db44e2..691baf94f1f 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -419,6 +419,7 @@ static HRESULT WINAPI HTMLEventObj_get_srcElement(IHTMLEventObj *iface, IHTMLEle static HRESULT WINAPI HTMLEventObj_get_altKey(IHTMLEventObj *iface, VARIANT_BOOL *p) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); + IDOMKeyboardEvent *keyboard_event; IDOMMouseEvent *mouse_event; cpp_bool ret = FALSE;
@@ -430,8 +431,11 @@ static HRESULT WINAPI HTMLEventObj_get_altKey(IHTMLEventObj *iface, VARIANT_BOOL return hres; }
- if(This->event && This->event->keyboard_event) - return IDOMKeyboardEvent_get_altKey(&This->event->IDOMKeyboardEvent_iface, p); + if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMKeyboardEvent, (void**)&keyboard_event))) { + HRESULT hres = IDOMKeyboardEvent_get_altKey(keyboard_event, p); + IDOMKeyboardEvent_Release(keyboard_event); + return hres; + }
*p = variant_bool(ret); return S_OK; @@ -440,6 +444,7 @@ static HRESULT WINAPI HTMLEventObj_get_altKey(IHTMLEventObj *iface, VARIANT_BOOL static HRESULT WINAPI HTMLEventObj_get_ctrlKey(IHTMLEventObj *iface, VARIANT_BOOL *p) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); + IDOMKeyboardEvent *keyboard_event; IDOMMouseEvent *mouse_event; cpp_bool ret = FALSE;
@@ -451,8 +456,11 @@ static HRESULT WINAPI HTMLEventObj_get_ctrlKey(IHTMLEventObj *iface, VARIANT_BOO return hres; }
- if(This->event && This->event->keyboard_event) - return IDOMKeyboardEvent_get_ctrlKey(&This->event->IDOMKeyboardEvent_iface, p); + if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMKeyboardEvent, (void**)&keyboard_event))) { + HRESULT hres = IDOMKeyboardEvent_get_ctrlKey(keyboard_event, p); + IDOMKeyboardEvent_Release(keyboard_event); + return hres; + }
*p = variant_bool(ret); return S_OK; @@ -461,6 +469,7 @@ static HRESULT WINAPI HTMLEventObj_get_ctrlKey(IHTMLEventObj *iface, VARIANT_BOO static HRESULT WINAPI HTMLEventObj_get_shiftKey(IHTMLEventObj *iface, VARIANT_BOOL *p) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); + IDOMKeyboardEvent *keyboard_event; IDOMMouseEvent *mouse_event; cpp_bool ret = FALSE;
@@ -472,8 +481,11 @@ static HRESULT WINAPI HTMLEventObj_get_shiftKey(IHTMLEventObj *iface, VARIANT_BO return hres; }
- if(This->event && This->event->keyboard_event) - return IDOMKeyboardEvent_get_shiftKey(&This->event->IDOMKeyboardEvent_iface, p); + if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMKeyboardEvent, (void**)&keyboard_event))) { + HRESULT hres = IDOMKeyboardEvent_get_shiftKey(keyboard_event, p); + IDOMKeyboardEvent_Release(keyboard_event); + return hres; + }
*p = variant_bool(ret); return S_OK; @@ -571,11 +583,15 @@ static HRESULT WINAPI HTMLEventObj_put_keyCode(IHTMLEventObj *iface, LONG v) static HRESULT WINAPI HTMLEventObj_get_keyCode(IHTMLEventObj *iface, LONG *p) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); + IDOMKeyboardEvent *keyboard_event;
TRACE("(%p)->(%p)\n", This, p);
- if(This->event && This->event->keyboard_event) - return IDOMKeyboardEvent_get_keyCode(&This->event->IDOMKeyboardEvent_iface, p); + if(This->event && SUCCEEDED(IDOMEvent_QueryInterface(&This->event->IDOMEvent_iface, &IID_IDOMKeyboardEvent, (void**)&keyboard_event))) { + HRESULT hres = IDOMKeyboardEvent_get_keyCode(keyboard_event, p); + IDOMKeyboardEvent_Release(keyboard_event); + return hres; + }
*p = 0; return S_OK; @@ -896,8 +912,6 @@ static HRESULT WINAPI DOMEvent_QueryInterface(IDOMEvent *iface, REFIID riid, voi *ppv = &This->IDOMEvent_iface; else if(IsEqualGUID(&IID_IDOMEvent, riid)) *ppv = &This->IDOMEvent_iface; - else if(This->keyboard_event && IsEqualGUID(&IID_IDOMKeyboardEvent, riid)) - *ppv = &This->IDOMKeyboardEvent_iface; else if(dispex_query_interface(&This->dispex, riid, ppv)) return *ppv ? S_OK : E_NOINTERFACE; else if(!This->query_interface || !(*ppv = This->query_interface(This, riid))) { @@ -930,8 +944,6 @@ static ULONG WINAPI DOMEvent_Release(IDOMEvent *iface) if(!ref) { if(This->destroy) This->destroy(This); - if(This->keyboard_event) - nsIDOMKeyEvent_Release(This->keyboard_event); if(This->target) IEventTarget_Release(&This->target->IEventTarget_iface); nsIDOMEvent_Release(This->nsevent); @@ -1888,47 +1900,53 @@ static void DOMMouseEvent_destroy(DOMEvent *event) nsIDOMMouseEvent_Release(This->nsevent); }
-static inline DOMEvent *impl_from_IDOMKeyboardEvent(IDOMKeyboardEvent *iface) +typedef struct { + DOMUIEvent ui_event; + IDOMKeyboardEvent IDOMKeyboardEvent_iface; + nsIDOMKeyEvent *nsevent; +} DOMKeyboardEvent; + +static inline DOMKeyboardEvent *impl_from_IDOMKeyboardEvent(IDOMKeyboardEvent *iface) { - return CONTAINING_RECORD(iface, DOMEvent, IDOMKeyboardEvent_iface); + return CONTAINING_RECORD(iface, DOMKeyboardEvent, IDOMKeyboardEvent_iface); }
static HRESULT WINAPI DOMKeyboardEvent_QueryInterface(IDOMKeyboardEvent *iface, REFIID riid, void **ppv) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); - return IDOMEvent_QueryInterface(&This->IDOMEvent_iface, riid, ppv); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); + return IDOMEvent_QueryInterface(&This->ui_event.event.IDOMEvent_iface, riid, ppv); }
static ULONG WINAPI DOMKeyboardEvent_AddRef(IDOMKeyboardEvent *iface) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); - return IDOMEvent_AddRef(&This->IDOMEvent_iface); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); + return IDOMEvent_AddRef(&This->ui_event.event.IDOMEvent_iface); }
static ULONG WINAPI DOMKeyboardEvent_Release(IDOMKeyboardEvent *iface) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); - return IDOMEvent_Release(&This->IDOMEvent_iface); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); + return IDOMEvent_Release(&This->ui_event.event.IDOMEvent_iface); }
static HRESULT WINAPI DOMKeyboardEvent_GetTypeInfoCount(IDOMKeyboardEvent *iface, UINT *pctinfo) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); - return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); + return IDispatchEx_GetTypeInfoCount(&This->ui_event.event.dispex.IDispatchEx_iface, pctinfo); }
static HRESULT WINAPI DOMKeyboardEvent_GetTypeInfo(IDOMKeyboardEvent *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); - return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); + return IDispatchEx_GetTypeInfo(&This->ui_event.event.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); }
static HRESULT WINAPI DOMKeyboardEvent_GetIDsOfNames(IDOMKeyboardEvent *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); - return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames, + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); + return IDispatchEx_GetIDsOfNames(&This->ui_event.event.dispex.IDispatchEx_iface, riid, rgszNames, cNames, lcid, rgDispId); }
@@ -1936,14 +1954,14 @@ static HRESULT WINAPI DOMKeyboardEvent_Invoke(IDOMKeyboardEvent *iface, DISPID d REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); - return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); + return IDispatchEx_Invoke(&This->ui_event.event.dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); }
static HRESULT WINAPI DOMKeyboardEvent_get_key(IDOMKeyboardEvent *iface, BSTR *p) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); nsAString key_str; nsresult nsres;
@@ -1951,19 +1969,19 @@ static HRESULT WINAPI DOMKeyboardEvent_get_key(IDOMKeyboardEvent *iface, BSTR *p
nsAString_Init(&key_str, NULL); - nsres = nsIDOMKeyEvent_GetKey(This->keyboard_event, &key_str); + nsres = nsIDOMKeyEvent_GetKey(This->nsevent, &key_str); return return_nsstr(nsres, &key_str, p); }
static HRESULT WINAPI DOMKeyboardEvent_get_location(IDOMKeyboardEvent *iface, ULONG *p) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); UINT32 r; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMKeyEvent_GetLocation(This->keyboard_event, &r); + nsres = nsIDOMKeyEvent_GetLocation(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1973,13 +1991,13 @@ static HRESULT WINAPI DOMKeyboardEvent_get_location(IDOMKeyboardEvent *iface, UL
static HRESULT WINAPI DOMKeyboardEvent_get_ctrlKey(IDOMKeyboardEvent *iface, VARIANT_BOOL *p) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); cpp_bool r; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMKeyEvent_GetCtrlKey(This->keyboard_event, &r); + nsres = nsIDOMKeyEvent_GetCtrlKey(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -1989,13 +2007,13 @@ static HRESULT WINAPI DOMKeyboardEvent_get_ctrlKey(IDOMKeyboardEvent *iface, VAR
static HRESULT WINAPI DOMKeyboardEvent_get_shiftKey(IDOMKeyboardEvent *iface, VARIANT_BOOL *p) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); cpp_bool r; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMKeyEvent_GetShiftKey(This->keyboard_event, &r); + nsres = nsIDOMKeyEvent_GetShiftKey(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -2005,13 +2023,13 @@ static HRESULT WINAPI DOMKeyboardEvent_get_shiftKey(IDOMKeyboardEvent *iface, VA
static HRESULT WINAPI DOMKeyboardEvent_get_altKey(IDOMKeyboardEvent *iface, VARIANT_BOOL *p) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); cpp_bool r; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMKeyEvent_GetAltKey(This->keyboard_event, &r); + nsres = nsIDOMKeyEvent_GetAltKey(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -2021,13 +2039,13 @@ static HRESULT WINAPI DOMKeyboardEvent_get_altKey(IDOMKeyboardEvent *iface, VARI
static HRESULT WINAPI DOMKeyboardEvent_get_metaKey(IDOMKeyboardEvent *iface, VARIANT_BOOL *p) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); cpp_bool r; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMKeyEvent_GetMetaKey(This->keyboard_event, &r); + nsres = nsIDOMKeyEvent_GetMetaKey(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -2037,13 +2055,13 @@ static HRESULT WINAPI DOMKeyboardEvent_get_metaKey(IDOMKeyboardEvent *iface, VAR
static HRESULT WINAPI DOMKeyboardEvent_get_repeat(IDOMKeyboardEvent *iface, VARIANT_BOOL *p) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); cpp_bool r; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMKeyEvent_GetRepeat(This->keyboard_event, &r); + nsres = nsIDOMKeyEvent_GetRepeat(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -2054,7 +2072,7 @@ static HRESULT WINAPI DOMKeyboardEvent_get_repeat(IDOMKeyboardEvent *iface, VARI static HRESULT WINAPI DOMKeyboardEvent_getModifierState(IDOMKeyboardEvent *iface, BSTR key, VARIANT_BOOL *state) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); FIXME("(%p)->(%s %p)\n", This, debugstr_w(key), state); return E_NOTIMPL; } @@ -2063,7 +2081,7 @@ static HRESULT WINAPI DOMKeyboardEvent_initKeyboardEvent(IDOMKeyboardEvent *ifac VARIANT_BOOL can_bubble, VARIANT_BOOL cancelable, IHTMLWindow2 *view, BSTR key, ULONG location, BSTR modifiers_list, VARIANT_BOOL repeat, BSTR locale) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); FIXME("(%p)->(%s %x %x %p %s %lu %s %x %s)\n", This, debugstr_w(type), can_bubble, cancelable, view, debugstr_w(key), location, debugstr_w(modifiers_list), repeat, debugstr_w(locale)); @@ -2072,13 +2090,13 @@ static HRESULT WINAPI DOMKeyboardEvent_initKeyboardEvent(IDOMKeyboardEvent *ifac
static HRESULT WINAPI DOMKeyboardEvent_get_keyCode(IDOMKeyboardEvent *iface, LONG *p) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); UINT32 r; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMKeyEvent_GetKeyCode(This->keyboard_event, &r); + nsres = nsIDOMKeyEvent_GetKeyCode(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -2088,13 +2106,13 @@ static HRESULT WINAPI DOMKeyboardEvent_get_keyCode(IDOMKeyboardEvent *iface, LON
static HRESULT WINAPI DOMKeyboardEvent_get_charCode(IDOMKeyboardEvent *iface, LONG *p) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); UINT32 r; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMKeyEvent_GetKeyCode(This->keyboard_event, &r); + nsres = nsIDOMKeyEvent_GetKeyCode(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -2104,13 +2122,13 @@ static HRESULT WINAPI DOMKeyboardEvent_get_charCode(IDOMKeyboardEvent *iface, LO
static HRESULT WINAPI DOMKeyboardEvent_get_which(IDOMKeyboardEvent *iface, LONG *p) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); UINT32 r; nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
- nsres = nsIDOMKeyEvent_GetWhich(This->keyboard_event, &r); + nsres = nsIDOMKeyEvent_GetWhich(This->nsevent, &r); if(NS_FAILED(nsres)) return E_FAIL;
@@ -2120,14 +2138,14 @@ static HRESULT WINAPI DOMKeyboardEvent_get_which(IDOMKeyboardEvent *iface, LONG
static HRESULT WINAPI DOMKeyboardEvent_get_char(IDOMKeyboardEvent *iface, VARIANT *p) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); FIXME("(%p)->(%p)\n", This, p); return E_NOTIMPL; }
static HRESULT WINAPI DOMKeyboardEvent_get_locale(IDOMKeyboardEvent *iface, BSTR *p) { - DOMEvent *This = impl_from_IDOMKeyboardEvent(iface); + DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); FIXME("(%p)->(%p)\n", This, p); return E_NOTIMPL; } @@ -2156,6 +2174,28 @@ static const IDOMKeyboardEventVtbl DOMKeyboardEventVtbl = { DOMKeyboardEvent_get_locale };
+static DOMKeyboardEvent *DOMKeyboardEvent_from_DOMEvent(DOMEvent *event) +{ + return CONTAINING_RECORD(event, DOMKeyboardEvent, ui_event.event); +} + +static void *DOMKeyboardEvent_query_interface(DOMEvent *event, REFIID riid) +{ + DOMKeyboardEvent *This = DOMKeyboardEvent_from_DOMEvent(event); + if(IsEqualGUID(&IID_IDOMKeyboardEvent, riid)) + return &This->IDOMKeyboardEvent_iface; + if(IsEqualGUID(&IID_IDOMUIEvent, riid)) + return &This->ui_event.IDOMUIEvent_iface; + return NULL; +} + +static void DOMKeyboardEvent_destroy(DOMEvent *event) +{ + DOMKeyboardEvent *This = DOMKeyboardEvent_from_DOMEvent(event); + DOMUIEvent_destroy(&This->ui_event.event); + nsIDOMKeyEvent_Release(This->nsevent); +} + typedef struct { DOMEvent event; IDOMCustomEvent IDOMCustomEvent_iface; @@ -2646,6 +2686,16 @@ static DOMEvent *mouse_event_ctor(void *iface) return &mouse_event->ui_event.event; }
+static DOMEvent *keyboard_event_ctor(void *iface) +{ + DOMKeyboardEvent *keyboard_event = event_ctor(sizeof(DOMKeyboardEvent), DOMKeyboardEvent_query_interface, DOMKeyboardEvent_destroy); + if(!keyboard_event) return NULL; + keyboard_event->IDOMKeyboardEvent_iface.lpVtbl = &DOMKeyboardEventVtbl; + keyboard_event->nsevent = iface; + fill_parent_ui_event(iface, &keyboard_event->ui_event); + return &keyboard_event->ui_event.event; +} + static DOMEvent *custom_event_ctor(void *iface) { DOMCustomEvent *custom_event = event_ctor(sizeof(DOMCustomEvent), DOMCustomEvent_query_interface, DOMCustomEvent_destroy); @@ -2673,6 +2723,7 @@ static DOMEvent *alloc_event(nsIDOMEvent *nsevent, compat_mode_t compat_mode, ev compat_mode_t compat_mode; } types_table[] = { { &IID_nsIDOMMouseEvent, &DOMMouseEvent_dispex, mouse_event_ctor }, + { &IID_nsIDOMKeyEvent, &DOMKeyboardEvent_dispex, keyboard_event_ctor }, { &IID_nsIDOMUIEvent, &DOMUIEvent_dispex, ui_event_ctor }, { &IID_nsIDOMCustomEvent, &DOMCustomEvent_dispex, custom_event_ctor }, { &IID_nsIDOMProgressEvent, &DOMProgressEvent_dispex, progress_event_ctor, COMPAT_MODE_IE10 }, @@ -2714,7 +2765,6 @@ static DOMEvent *alloc_event(nsIDOMEvent *nsevent, compat_mode_t compat_mode, ev }
event->IDOMEvent_iface.lpVtbl = &DOMEventVtbl; - event->IDOMKeyboardEvent_iface.lpVtbl = &DOMKeyboardEventVtbl; event->ref = 1; event->event_id = event_id; if(event_id != EVENTID_LAST) { @@ -2730,12 +2780,6 @@ static DOMEvent *alloc_event(nsIDOMEvent *nsevent, compat_mode_t compat_mode, ev
event->time_stamp = get_time_stamp();
- nsres = nsIDOMEvent_QueryInterface(nsevent, &IID_nsIDOMKeyEvent, (void**)&event->keyboard_event); - if(NS_SUCCEEDED(nsres)) - dispex_data = &DOMKeyboardEvent_dispex; - else - event->keyboard_event = NULL; - init_dispatch(&event->dispex, (IUnknown*)&event->IDOMEvent_iface, dispex_data, compat_mode); return event; } diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index 207c0a7aaab..d0c72d87a5d 100644 --- a/dlls/mshtml/htmlevent.h +++ b/dlls/mshtml/htmlevent.h @@ -67,14 +67,12 @@ typedef enum { typedef struct DOMEvent { DispatchEx dispex; IDOMEvent IDOMEvent_iface; - IDOMKeyboardEvent IDOMKeyboardEvent_iface;
LONG ref; void *(*query_interface)(struct DOMEvent*,REFIID); void (*destroy)(struct DOMEvent*);
nsIDOMEvent *nsevent; - nsIDOMKeyEvent *keyboard_event;
eventid_t event_id; WCHAR *type;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 691baf94f1f..c3cf4d2a14b 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -78,7 +78,7 @@ static const WCHAR *event_types[] = { L"MouseEvent", L"Event", /* FIXME */ L"Event", /* FIXME */ - L"Event", /* FIXME */ + L"Event", /* We don't use Gecko's message events */ L"ProgressEvent", L"Event" /* FIXME */ };
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/tests/xhr.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/mshtml/tests/xhr.js b/dlls/mshtml/tests/xhr.js index 8d9af26a943..58665499052 100644 --- a/dlls/mshtml/tests/xhr.js +++ b/dlls/mshtml/tests/xhr.js @@ -54,7 +54,7 @@ function test_xhr() { ok(loadstart, "onloadstart not fired before onloadend"); var props = [ "initProgressEvent", "lengthComputable", "loaded", "total" ]; for(var i = 0; i < props.length; i++) - ok(props[i] in e, props[i] + " not available in loadstart"); + ok(props[i] in e, props[i] + " not available in loadend"); next_test(); }; }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 13 +++++++++++-- dlls/mshtml/tests/xhr.js | 5 +++++ 2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index c3cf4d2a14b..4cda80c017c 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -2498,8 +2498,17 @@ static HRESULT WINAPI DOMProgressEvent_Invoke(IDOMProgressEvent *iface, DISPID d static HRESULT WINAPI DOMProgressEvent_get_lengthComputable(IDOMProgressEvent *iface, VARIANT_BOOL *p) { DOMProgressEvent *This = impl_from_IDOMProgressEvent(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsresult nsres; + cpp_bool b; + + TRACE("(%p)->(%p)\n", This, p); + + nsres = nsIDOMProgressEvent_GetLengthComputable(This->nsevent, &b); + if(NS_FAILED(nsres)) + return map_nsresult(nsres); + + *p = b ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; }
static HRESULT WINAPI DOMProgressEvent_get_loaded(IDOMProgressEvent *iface, ULONGLONG *p) diff --git a/dlls/mshtml/tests/xhr.js b/dlls/mshtml/tests/xhr.js index 58665499052..9af44850a39 100644 --- a/dlls/mshtml/tests/xhr.js +++ b/dlls/mshtml/tests/xhr.js @@ -47,6 +47,7 @@ function test_xhr() { var props = [ "initProgressEvent", "lengthComputable", "loaded", "total" ]; for(var i = 0; i < props.length; i++) ok(props[i] in e, props[i] + " not available in loadstart"); + ok(e.lengthComputable === false, "lengthComputable in loadstart = " + e.lengthComputable); loadstart = true; }; xhr.onloadend = function(e) { @@ -55,6 +56,7 @@ function test_xhr() { var props = [ "initProgressEvent", "lengthComputable", "loaded", "total" ]; for(var i = 0; i < props.length; i++) ok(props[i] in e, props[i] + " not available in loadend"); + ok(e.lengthComputable === true, "lengthComputable in loadend = " + e.lengthComputable); next_test(); }; } @@ -171,6 +173,9 @@ function test_timeout() { else ok(props[r] in e, props[r] + " not available"); } + if(v >= 10) { + ok(e.lengthComputable === false, "lengthComputable = " + e.lengthComputable); + } next_test(); }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 6 ++++-- dlls/mshtml/tests/xhr.js | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 4cda80c017c..97e9add3406 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -2514,8 +2514,10 @@ static HRESULT WINAPI DOMProgressEvent_get_lengthComputable(IDOMProgressEvent *i static HRESULT WINAPI DOMProgressEvent_get_loaded(IDOMProgressEvent *iface, ULONGLONG *p) { DOMProgressEvent *This = impl_from_IDOMProgressEvent(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + return map_nsresult(nsIDOMProgressEvent_GetLoaded(This->nsevent, p)); }
static HRESULT WINAPI DOMProgressEvent_get_total(IDOMProgressEvent *iface, ULONGLONG *p) diff --git a/dlls/mshtml/tests/xhr.js b/dlls/mshtml/tests/xhr.js index 9af44850a39..c60107c556f 100644 --- a/dlls/mshtml/tests/xhr.js +++ b/dlls/mshtml/tests/xhr.js @@ -48,6 +48,7 @@ function test_xhr() { for(var i = 0; i < props.length; i++) ok(props[i] in e, props[i] + " not available in loadstart"); ok(e.lengthComputable === false, "lengthComputable in loadstart = " + e.lengthComputable); + ok(e.loaded === 0, "loaded in loadstart = " + e.loaded); loadstart = true; }; xhr.onloadend = function(e) { @@ -57,6 +58,8 @@ function test_xhr() { for(var i = 0; i < props.length; i++) ok(props[i] in e, props[i] + " not available in loadend"); ok(e.lengthComputable === true, "lengthComputable in loadend = " + e.lengthComputable); + todo_wine. + ok(e.loaded === xml.length, "loaded in loadend = " + e.loaded); next_test(); }; } @@ -175,6 +178,7 @@ function test_timeout() { } if(v >= 10) { ok(e.lengthComputable === false, "lengthComputable = " + e.lengthComputable); + ok(e.loaded === 0, "loaded = " + e.loaded); } next_test(); }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 12 ++++++++++-- dlls/mshtml/tests/xhr.js | 4 ++++ 2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 97e9add3406..5d3d56595ba 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -2523,8 +2523,16 @@ static HRESULT WINAPI DOMProgressEvent_get_loaded(IDOMProgressEvent *iface, ULON static HRESULT WINAPI DOMProgressEvent_get_total(IDOMProgressEvent *iface, ULONGLONG *p) { DOMProgressEvent *This = impl_from_IDOMProgressEvent(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + cpp_bool b; + + TRACE("(%p)->(%p)\n", This, p); + + if(NS_FAILED(nsIDOMProgressEvent_GetLengthComputable(This->nsevent, &b)) || !b) { + *p = ~0; + return S_OK; + } + + return map_nsresult(nsIDOMProgressEvent_GetTotal(This->nsevent, p)); }
static HRESULT WINAPI DOMProgressEvent_initProgressEvent(IDOMProgressEvent *iface, BSTR type, VARIANT_BOOL can_bubble, diff --git a/dlls/mshtml/tests/xhr.js b/dlls/mshtml/tests/xhr.js index c60107c556f..cc8a03dadb4 100644 --- a/dlls/mshtml/tests/xhr.js +++ b/dlls/mshtml/tests/xhr.js @@ -49,6 +49,7 @@ function test_xhr() { ok(props[i] in e, props[i] + " not available in loadstart"); ok(e.lengthComputable === false, "lengthComputable in loadstart = " + e.lengthComputable); ok(e.loaded === 0, "loaded in loadstart = " + e.loaded); + ok(e.total === 18446744073709552000, "total in loadstart = " + e.total); loadstart = true; }; xhr.onloadend = function(e) { @@ -60,6 +61,8 @@ function test_xhr() { ok(e.lengthComputable === true, "lengthComputable in loadend = " + e.lengthComputable); todo_wine. ok(e.loaded === xml.length, "loaded in loadend = " + e.loaded); + todo_wine. + ok(e.total === xml.length, "total in loadend = " + e.total); next_test(); }; } @@ -179,6 +182,7 @@ function test_timeout() { if(v >= 10) { ok(e.lengthComputable === false, "lengthComputable = " + e.lengthComputable); ok(e.loaded === 0, "loaded = " + e.loaded); + ok(e.total === 18446744073709552000, "total = " + e.total); } next_test(); }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Currently we don't support 64-bit progress values (BINDSTATUS_64BIT_PROGRESS is not implemented in wine), so this is limited to 4 GB.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/binding.h | 4 ++- dlls/mshtml/navigate.c | 68 ++++++++++++++++++++++++++++++---------- dlls/mshtml/nsiface.idl | 11 +++++++ dlls/mshtml/script.c | 2 +- dlls/mshtml/tests/xhr.js | 2 -- 5 files changed, 67 insertions(+), 20 deletions(-)
diff --git a/dlls/mshtml/binding.h b/dlls/mshtml/binding.h index 9a043864927..5d2915a836b 100644 --- a/dlls/mshtml/binding.h +++ b/dlls/mshtml/binding.h @@ -104,6 +104,8 @@ struct nsChannelBSC { nsChannel *nschannel; nsIStreamListener *nslistener; nsISupports *nscontext; + ULONG progress; + ULONG total; BOOL is_js; BOOL is_doc_channel; BOOL response_processed; @@ -117,7 +119,7 @@ struct BSCallbackVtbl { HRESULT (*start_binding)(BSCallback*); HRESULT (*stop_binding)(BSCallback*,HRESULT); HRESULT (*read_data)(BSCallback*,IStream*); - HRESULT (*on_progress)(BSCallback*,ULONG,LPCWSTR); + HRESULT (*on_progress)(BSCallback*,ULONG,ULONG,ULONG,LPCWSTR); HRESULT (*on_response)(BSCallback*,DWORD,LPCWSTR); HRESULT (*beginning_transaction)(BSCallback*,WCHAR**); }; diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index 6f684630cd6..ef764bde58c 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -326,7 +326,7 @@ static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface, TRACE("%p)->(%lu %lu %lu %s)\n", This, ulProgress, ulProgressMax, ulStatusCode, debugstr_w(szStatusText));
- return This->vtbl->on_progress(This, ulStatusCode, szStatusText); + return This->vtbl->on_progress(This, ulProgress, ulProgressMax, ulStatusCode, szStatusText); }
static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface, @@ -1067,6 +1067,37 @@ static void on_stop_nsrequest(nsChannelBSC *This, HRESULT result) } }
+static void notify_progress(nsChannelBSC *This) +{ + nsChannel *nschannel = This->nschannel; + nsIProgressEventSink *sink = NULL; + nsresult nsres; + + if(!nschannel) + return; + + if(nschannel->notif_callback) + if(NS_FAILED(nsIInterfaceRequestor_GetInterface(nschannel->notif_callback, &IID_nsIProgressEventSink, (void**)&sink))) + sink = NULL; + + if(!sink && nschannel->load_group) { + nsIRequestObserver *req_observer; + + if(NS_SUCCEEDED(nsILoadGroup_GetGroupObserver(nschannel->load_group, &req_observer)) && req_observer) { + nsres = nsIRequestObserver_QueryInterface(req_observer, &IID_nsIProgressEventSink, (void**)&sink); + nsIRequestObserver_Release(req_observer); + if(NS_FAILED(nsres)) + sink = NULL; + } + } + + if(sink) { + nsIProgressEventSink_OnProgress(sink, (nsIRequest*)&nschannel->nsIHttpChannel_iface, This->nscontext, + This->progress, (This->total == ~0) ? -1 : This->total); + nsIProgressEventSink_Release(sink); + } +} + static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream) { DWORD read; @@ -1147,6 +1178,8 @@ static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream) return hres; }
+ notify_progress(This); + nsres = nsIStreamListener_OnDataAvailable(This->nslistener, (nsIRequest*)&This->nschannel->nsIHttpChannel_iface, This->nscontext, &This->nsstream->nsIInputStream_iface, This->bsc.read-This->nsstream->buf_size, @@ -1656,7 +1689,7 @@ static void handle_extern_mime_navigation(nsChannelBSC *This) IUri_Release(uri); }
-static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG status_code, LPCWSTR status_text) +static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG progress, ULONG total, ULONG status_code, LPCWSTR status_text) { nsChannelBSC *This = nsChannelBSC_from_BSCallback(bsc);
@@ -1684,21 +1717,24 @@ static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG status_code, LPCW DWORD status, size = sizeof(DWORD); HRESULT hres;
- if(!This->bsc.binding) - break; - - hres = IBinding_QueryInterface(This->bsc.binding, &IID_IWinInetHttpInfo, (void**)&http_info); - if(FAILED(hres)) - break; - - hres = IWinInetHttpInfo_QueryInfo(http_info, - HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL, NULL); - IWinInetHttpInfo_Release(http_info); - if(FAILED(hres) || status == HTTP_STATUS_OK) - break; - - handle_navigation_error(This, status); + if(This->bsc.binding) { + hres = IBinding_QueryInterface(This->bsc.binding, &IID_IWinInetHttpInfo, (void**)&http_info); + if(SUCCEEDED(hres)) { + hres = IWinInetHttpInfo_QueryInfo(http_info, + HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL, NULL); + IWinInetHttpInfo_Release(http_info); + if(SUCCEEDED(hres) && status != HTTP_STATUS_OK) + handle_navigation_error(This, status); + } + } + /* fall through */ } + case BINDSTATUS_DOWNLOADINGDATA: + case BINDSTATUS_ENDDOWNLOADDATA: + /* Defer it to just before calling OnDataAvailable, otherwise it can have wrong state */ + This->progress = progress; + This->total = total; + break; }
return S_OK; diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl index c4b479b16e3..f6e0a909278 100644 --- a/dlls/mshtml/nsiface.idl +++ b/dlls/mshtml/nsiface.idl @@ -771,6 +771,17 @@ interface nsIChannelEventSink : nsISupports nsIAsyncVerifyRedirectCallback *callback); }
+[ + object, + uuid(87d55fba-cb7e-4f38-84c1-5c6c2b2a55e9), + local +] +interface nsIProgressEventSink : nsISupports +{ + nsresult OnProgress(nsIRequest *aRequest, nsISupports *aContext, int64_t aProgress, int64_t aProgressMax); + nsresult OnStatus(nsIRequest *aRequest, nsISupports *aContext, nsresult aStatus, const char16_t *aStatusArg); +} + [ object, uuid(79de76e5-994e-4f6b-81aa-42d9adb6e67e), diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c index e49449a61f8..769ca72db6f 100644 --- a/dlls/mshtml/script.c +++ b/dlls/mshtml/script.c @@ -1053,7 +1053,7 @@ static HRESULT ScriptBSC_read_data(BSCallback *bsc, IStream *stream) return S_OK; }
-static HRESULT ScriptBSC_on_progress(BSCallback *bsc, ULONG status_code, LPCWSTR status_text) +static HRESULT ScriptBSC_on_progress(BSCallback *bsc, ULONG progress, ULONG total, ULONG status_code, LPCWSTR status_text) { return S_OK; } diff --git a/dlls/mshtml/tests/xhr.js b/dlls/mshtml/tests/xhr.js index cc8a03dadb4..dd3750632c7 100644 --- a/dlls/mshtml/tests/xhr.js +++ b/dlls/mshtml/tests/xhr.js @@ -59,9 +59,7 @@ function test_xhr() { for(var i = 0; i < props.length; i++) ok(props[i] in e, props[i] + " not available in loadend"); ok(e.lengthComputable === true, "lengthComputable in loadend = " + e.lengthComputable); - todo_wine. ok(e.loaded === xml.length, "loaded in loadend = " + e.loaded); - todo_wine. ok(e.total === xml.length, "total in loadend = " + e.total); next_test(); };
Updated (but kept the compat_mode in the table, rest is changed though). I've added a fix for the OnProgress notification now since I finally found out the issue, it's at the end so its effects can be seen.
Jacek Caban (@jacek) commented about dlls/mshtml/navigate.c:
return hres; }
notify_progress(This);
Why do you call it here? on_progress() seems more appropriate.
On Mon Jul 25 15:03:04 2022 +0000, Gabriel Iv��ncescu wrote:
To be honest, now that I fiddled with it, I should probably keep the compat_mode in the array, because I also have the dispex in the array, and it fits neatly in one line there, instead of having to add it as an output arg in each ctor and then assign it in each one on top of it, which IMO is mostly duplicated code for no reason, when a data table can provide this info in one place���
I'm not sure I follow. You could simply move init_dispatch() call to event_ctor() and pass dispex descriptor as a parameter. vtbl and ref initialization could also be moved.
Well, as mentioned in the comment, it has to be deferred until *after* nsIStreamListener_OnStartRequest is called, because that's when the state is changed on Gecko's XHR (not sure about the others), and that was the most straightforward place for me to add it.
If you call it directly in on_progress, the tests fail. The reason is that Gecko's XHR OnProgress checks the state first to see whether it's uploading or downloading, and because OnStartRequest was not called yet to change the state, it assumes it's an upload progress notification. And so the download progress remains 0.
On Mon Jul 25 16:32:08 2022 +0000, Gabriel Iv��ncescu wrote:
Well, as mentioned in the comment, it has to be deferred until *after* nsIStreamListener_OnStartRequest is called, because that's when the state is changed on Gecko's XHR (not sure about the others), and that was the most straightforward place for me to add it. If you call it directly in on_progress, the tests fail. The reason is that Gecko's XHR OnProgress checks the state first to see whether it's uploading or downloading, and because OnStartRequest was not called yet to change the state, it assumes it's an upload progress notification. And so the download progress remains 0.
Sure, but that applies only to the first call OnStartRequest(). Actually, looking closer at this, we may need it both in read_data() and on_progress(), so the patch is fine for now.