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 | 87 ++++++++++++++++++++++++++--------------- dlls/mshtml/nsiface.idl | 14 +++++++ 2 files changed, 69 insertions(+), 32 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 0f6525af86a..4a5b4f5dd0e 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,36 +2511,42 @@ dispex_static_data_t DOMProgressEvent_dispex = { DOMProgressEvent_iface_tids };
-static BOOL check_event_iface(nsIDOMEvent *event, REFIID riid) +static void custom_event_ctor(void *event, void *iface) { - nsISupports *iface; - nsresult nsres; - - nsres = nsIDOMEvent_QueryInterface(event, riid, (void**)&iface); - if(NS_FAILED(nsres)) - return FALSE; + DOMCustomEvent *custom_event = event; + custom_event->IDOMCustomEvent_iface.lpVtbl = &DOMCustomEventVtbl; + nsIDOMCustomEvent_Release(iface); +}
- nsISupports_Release(iface); - return TRUE; +static void progress_event_ctor(void *event, void *iface) +{ + DOMProgressEvent *progress_event = event; + progress_event->IDOMProgressEvent_iface.lpVtbl = &DOMProgressEventVtbl; + progress_event->nsevent = iface; }
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; + void (*ctor)(void *event, void *iface); + void *(*query_interface)(DOMEvent*,REFIID); + void (*destroy)(DOMEvent*); + unsigned size; + compat_mode_t compat_mode; + } types_table[] = { + { &IID_nsIDOMCustomEvent, &DOMCustomEvent_dispex, custom_event_ctor, DOMCustomEvent_query_interface, + DOMCustomEvent_destroy, sizeof(DOMCustomEvent) }, + { &IID_nsIDOMProgressEvent, &DOMProgressEvent_dispex, progress_event_ctor, DOMProgressEvent_query_interface, + DOMProgressEvent_destroy, sizeof(DOMProgressEvent), 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) { + if(event_id == EVENTID_MESSAGE) { DOMMessageEvent *message_event = heap_alloc_zero(sizeof(*message_event)); if(!message_event) return NULL; @@ -2543,19 +2556,29 @@ static DOMEvent *alloc_event(nsIDOMEvent *nsevent, compat_mode_t compat_mode, ev 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)) { + if(!(event = heap_alloc_zero(types_table[i].size))) + return NULL; + event->query_interface = types_table[i].query_interface; + event->destroy = types_table[i].destroy; + + /* Transfer the iface ownership to the ctor */ + types_table[i].ctor(event, iface); + 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),