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),