-- v4: mshtml: Silence a FIXME when parameter is missing. mshtml: Allocate events via event type. mshtml: Expand event_info to include a special entry for EVENTID_LAST. mshtml: Use actual Gecko event type for MessageEvent and StorageEvent. mshtml: Implement url prop for StorageEvent. include/mshtml: Move some forward interface declarations to match Windows SDK. mshtml: Override document.URL's name when adding it from the mshtml typelib.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Because the typelib should contain the lowercase `url` symbol instead.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 18 +++++++++++------- dlls/mshtml/htmldoc.c | 2 ++ dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/tests/dom.js | 5 +++++ 4 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 5007f9a5d30..90650e5acc4 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -270,16 +270,20 @@ static BOOL is_arg_type_supported(VARTYPE vt) }
static void add_func_info(dispex_data_t *data, tid_t tid, const FUNCDESC *desc, ITypeInfo *dti, - dispex_hook_invoke_t hook) + dispex_hook_invoke_t hook, const WCHAR *name_override) { func_info_t *info; BSTR name; HRESULT hres;
- hres = ITypeInfo_GetDocumentation(dti, desc->memid, &name, NULL, NULL, NULL); - if(FAILED(hres)) { - WARN("GetDocumentation failed: %08lx\n", hres); - return; + if(name_override) + name = SysAllocString(name_override); + else { + hres = ITypeInfo_GetDocumentation(dti, desc->memid, &name, NULL, NULL, NULL); + if(FAILED(hres)) { + WARN("GetDocumentation failed: %08lx\n", hres); + return; + } }
for(info = data->funcs; info < data->funcs+data->func_cnt; info++) { @@ -441,9 +445,9 @@ static HRESULT process_interface(dispex_data_t *data, tid_t tid, ITypeInfo *disp hook = NULL; }
- if(!hook || hook->invoke) { + if(!hook || hook->invoke || hook->name) { add_func_info(data, tid, funcdesc, disp_typeinfo ? disp_typeinfo : typeinfo, - hook ? hook->invoke : NULL); + hook ? hook->invoke : NULL, hook ? hook->name : NULL); }
ITypeInfo_ReleaseFuncDesc(typeinfo, funcdesc); diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index aa3efe27c68..0c96d73eb76 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -5975,6 +5975,7 @@ static const tid_t HTMLDocumentNode_iface_tids[] = { static void HTMLDocumentNode_init_dispex_info(dispex_data_t *info, compat_mode_t mode) { static const dispex_hook_t document2_hooks[] = { + {DISPID_IHTMLDOCUMENT2_URL, NULL, L"URL"}, {DISPID_IHTMLDOCUMENT2_LOCATION, HTMLDocumentNode_location_hook}, {DISPID_UNKNOWN} }; @@ -6307,6 +6308,7 @@ static const tid_t HTMLDocumentObj_iface_tids[] = { static void HTMLDocumentObj_init_dispex_info(dispex_data_t *info, compat_mode_t mode) { static const dispex_hook_t document2_hooks[] = { + {DISPID_IHTMLDOCUMENT2_URL, NULL, L"URL"}, {DISPID_IHTMLDOCUMENT2_LOCATION, HTMLDocumentObj_location_hook}, {DISPID_UNKNOWN} }; diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 18104afc10a..4ce90d3f17e 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -359,6 +359,7 @@ typedef HRESULT (*dispex_hook_invoke_t)(DispatchEx*,WORD,DISPPARAMS*,VARIANT*, typedef struct { DISPID dispid; dispex_hook_invoke_t invoke; + const WCHAR *name; } dispex_hook_t;
struct DispatchEx { diff --git a/dlls/mshtml/tests/dom.js b/dlls/mshtml/tests/dom.js index e82424e5c55..43c52d89757 100644 --- a/dlls/mshtml/tests/dom.js +++ b/dlls/mshtml/tests/dom.js @@ -18,6 +18,11 @@
var tests = [];
+sync_test("url", function() { + ok(document.URL === "http://winetest.example.org/index.html?dom.js", "document.URL = " + document.URL); + ok(!("documentURI" in document), "documentURI in document"); +}); + sync_test("input_selection", function() { var input = document.createElement("input"); input.type = "text";
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=124513
Your paranoid android.
=== w10pro64_ja (64 bit report) ===
mshtml: htmldoc.c:350: Test failed: expected Exec_SETTITLE htmldoc.c:2859: Test failed: unexpected call Exec_SETTITLE
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Currently, these forward declarations make widl add IHTMLDocument2's `URL` symbol before the other, lowercased, `url` symbols to the type library (from IHTMLMetaElement, IDOMStorageEvent, etc). Since the typelib symbols are case insensitive, `URL` ends up stored instead of `url`, which doesn't match native.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- include/mshtml.idl | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/include/mshtml.idl b/include/mshtml.idl index aa243897405..1abd3e99f77 100644 --- a/include/mshtml.idl +++ b/include/mshtml.idl @@ -395,9 +395,7 @@ interface IHTMLDOMConstructor : IDispatch [propget, id(DISPID_IHTMLDOMCONSTRUCTOR_CONSTRUCTOR), hidden] \ IDispatch *constructor()
-interface IHTMLCaret; interface IHTMLComputedStyle; -interface IHTMLDocument2; interface IHTMLDocument7; interface IHTMLElement; interface IHTMLElement2; @@ -414,14 +412,6 @@ interface IHTMLWindow5; interface IHTMLWindow6; interface IHTMLWindow7; interface IDOMEvent; -interface IDisplayPointer; -interface IDisplayServices; -interface ILineInfo; -interface IMarkupPointer; -interface IMarkupContainer; -interface ISegmentList; -interface IHTMLChangeLog; -interface IHTMLChangeSink; interface ISVGSVGElement; interface IHTMLDOMRange; interface IHTMLStyleSheet; @@ -19574,6 +19564,8 @@ interface IHTMLFramesCollection2 : IDispatch HRESULT length([retval, out] LONG *p); }
+interface IHTMLDocument2; + /***************************************************************************** * IHTMLScreen interface */ @@ -28841,6 +28833,16 @@ interface IHTMLComputedStyle : IUnknown HRESULT IsEqual([in] IHTMLComputedStyle *pComputedStyle,[out] VARIANT_BOOL *pfEqual); };
+interface IHTMLCaret; +interface IDisplayPointer; +interface IDisplayServices; +interface ILineInfo; +interface IMarkupPointer; +interface IMarkupContainer; +interface ISegmentList; +interface IHTMLChangeLog; +interface IHTMLChangeSink; + /***************************************************************************** * IDisplayPointer interface */
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 18 +++++++++++++++--- dlls/mshtml/htmlevent.h | 2 +- dlls/mshtml/htmlstorage.c | 4 +++- dlls/mshtml/tests/documentmode.js | 8 +++++--- dlls/mshtml/tests/events.c | 5 +++++ 5 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 7d13ac5b3fb..f08d4f6568c 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -2616,6 +2616,7 @@ typedef struct { BSTR key; BSTR old_value; BSTR new_value; + BSTR url; } DOMStorageEvent;
static inline DOMStorageEvent *impl_from_IDOMStorageEvent(IDOMStorageEvent *iface) @@ -2710,8 +2711,13 @@ static HRESULT WINAPI DOMStorageEvent_get_newValue(IDOMStorageEvent *iface, BSTR static HRESULT WINAPI DOMStorageEvent_get_url(IDOMStorageEvent *iface, BSTR *p) { DOMStorageEvent *This = impl_from_IDOMStorageEvent(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + if(This->url) + return (*p = SysAllocStringLen(This->url, SysStringLen(This->url))) ? S_OK : E_OUTOFMEMORY; + *p = NULL; + return S_OK; }
static HRESULT WINAPI DOMStorageEvent_get_storageArea(IDOMStorageEvent *iface, IHTMLStorage **p) @@ -2766,6 +2772,7 @@ static void DOMStorageEvent_destroy(DOMEvent *event) SysFreeString(storage_event->key); SysFreeString(storage_event->old_value); SysFreeString(storage_event->new_value); + SysFreeString(storage_event->url); }
static const tid_t DOMEvent_iface_tids[] = { @@ -3120,7 +3127,7 @@ HRESULT create_message_event(HTMLDocumentNode *doc, VARIANT *data, DOMEvent **re }
HRESULT create_storage_event(HTMLDocumentNode *doc, BSTR key, BSTR old_value, BSTR new_value, - BOOL commit, DOMEvent **ret) + const WCHAR *url, BOOL commit, DOMEvent **ret) { DOMStorageEvent *storage_event; DOMEvent *event; @@ -3140,6 +3147,11 @@ HRESULT create_storage_event(HTMLDocumentNode *doc, BSTR key, BSTR old_value, BS } }
+ if(url && !(storage_event->url = SysAllocString(url))) { + IDOMEvent_Release(&event->IDOMEvent_iface); + return E_OUTOFMEMORY; + } + *ret = event; return S_OK; } diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index ee0c7831009..fb2b395ca7a 100644 --- a/dlls/mshtml/htmlevent.h +++ b/dlls/mshtml/htmlevent.h @@ -114,7 +114,7 @@ HRESULT create_document_event(HTMLDocumentNode*,eventid_t,DOMEvent**) DECLSPEC_H HRESULT create_document_event_str(HTMLDocumentNode*,const WCHAR*,IDOMEvent**) DECLSPEC_HIDDEN; HRESULT create_event_from_nsevent(nsIDOMEvent*,compat_mode_t,DOMEvent**) DECLSPEC_HIDDEN; HRESULT create_message_event(HTMLDocumentNode*,VARIANT*,DOMEvent**) DECLSPEC_HIDDEN; -HRESULT create_storage_event(HTMLDocumentNode*,BSTR,BSTR,BSTR,BOOL,DOMEvent**) DECLSPEC_HIDDEN; +HRESULT create_storage_event(HTMLDocumentNode*,BSTR,BSTR,BSTR,const WCHAR*,BOOL,DOMEvent**) DECLSPEC_HIDDEN;
void init_nsevents(HTMLDocumentNode*) DECLSPEC_HIDDEN; void release_nsevents(HTMLDocumentNode*) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/htmlstorage.c b/dlls/mshtml/htmlstorage.c index f411c6cb122..bf93e28fdf6 100644 --- a/dlls/mshtml/htmlstorage.c +++ b/dlls/mshtml/htmlstorage.c @@ -235,6 +235,7 @@ struct send_storage_event_ctx { BSTR key; BSTR old_value; BSTR new_value; + const WCHAR *url; };
static HRESULT push_storage_event_task(struct send_storage_event_ctx *ctx, HTMLInnerWindow *window, BOOL commit) @@ -243,7 +244,7 @@ static HRESULT push_storage_event_task(struct send_storage_event_ctx *ctx, HTMLI DOMEvent *event; HRESULT hres;
- hres = create_storage_event(window->doc, ctx->key, ctx->old_value, ctx->new_value, commit, &event); + hres = create_storage_event(window->doc, ctx->key, ctx->old_value, ctx->new_value, ctx->url, commit, &event); if(FAILED(hres)) return hres;
@@ -327,6 +328,7 @@ static HRESULT send_storage_event(HTMLStorage *storage, BSTR key, BSTR old_value goto done; get_top_window(window->base.outer_window, &top_window);
+ ctx.url = window->base.outer_window->url; ctx.key = key; ctx.old_value = old_value; ctx.new_value = new_value; diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 9532f529332..90223d53f83 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -1322,7 +1322,7 @@ async_test("storage events", function() { } }
- function test_event(e, key, oldValue, newValue) { + function test_event(e, idx, key, oldValue, newValue) { if(v < 9) { ok(e === undefined, "event not undefined in legacy mode: " + e); return; @@ -1333,6 +1333,8 @@ async_test("storage events", function() { ok(e.key === key, "key = " + e.key + ", expected " + key); ok(e.oldValue === oldValue, "oldValue = " + e.oldValue + ", expected " + oldValue); ok(e.newValue === newValue, "newValue = " + e.newValue + ", expected " + newValue); + s = (idx ? iframe.contentWindow : window)["location"]["href"]; + ok(e.url === s, "url = " + e.url + ", expected " + s); }
function expect(idx, key, oldValue, newValue, quirk) { @@ -1352,10 +1354,10 @@ async_test("storage events", function() {
(v < 9 ? document2 : window2)["onstorage"] = function(e) { (local && idx ? document2 : (local || v < 9 ? document : window))[local ? "onstoragecommit" : "onstorage"] = function(e) { - test_event(e, local ? "" : key, local ? "" : oldValue, local ? "" : newValue); + test_event(e, idx, local ? "" : key, local ? "" : oldValue, local ? "" : newValue); next(); } - test_event(e, key, oldValue, newValue); + test_event(e, idx, key, oldValue, newValue); } } } diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index ff64db7130b..1819bc6bdd9 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -2925,6 +2925,11 @@ static void test_storage_event(DISPPARAMS *params, BOOL doc_onstorage) "newValue = %s\n", wine_dbgstr_w(bstr)); SysFreeString(bstr);
+ hres = IDOMStorageEvent_get_url(event, &bstr); + ok_(__FILE__,line)(hres == S_OK, "get_url failed: %08lx\n", hres); + ok_(__FILE__,line)(!wcscmp(bstr, L"http://winetest.example.org/"), "url = %s\n", wine_dbgstr_w(bstr)); + SysFreeString(bstr); + IDOMStorageEvent_Release(event); }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index f08d4f6568c..e1bac2400a9 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -68,6 +68,7 @@ typedef enum { EVENT_TYPE_DRAG, EVENT_TYPE_MESSAGE, EVENT_TYPE_PROGRESS, + EVENT_TYPE_STORAGE, EVENT_TYPE_CLIPBOARD } event_type_t;
@@ -78,8 +79,9 @@ static const WCHAR *event_types[] = { L"MouseEvent", L"Event", /* FIXME */ L"Event", /* FIXME */ - L"Event", /* We don't use Gecko's message events */ + L"MessageEvent", L"ProgressEvent", + L"StorageEvent", L"Event" /* FIXME */ };
@@ -191,9 +193,9 @@ static const event_info_t event_info[] = { EVENT_FIXME}, {L"selectstart", EVENT_TYPE_EVENT, DISPID_EVMETH_ONSELECTSTART, EVENT_FIXME | EVENT_BUBBLES | EVENT_CANCELABLE}, - {L"storage", EVENT_TYPE_EVENT, DISPID_EVMETH_ONSTORAGE, + {L"storage", EVENT_TYPE_STORAGE, DISPID_EVMETH_ONSTORAGE, 0}, - {L"storagecommit", EVENT_TYPE_EVENT, DISPID_EVMETH_ONSTORAGECOMMIT, + {L"storagecommit", EVENT_TYPE_STORAGE, DISPID_EVMETH_ONSTORAGECOMMIT, 0}, {L"submit", EVENT_TYPE_EVENT, DISPID_EVMETH_ONSUBMIT, EVENT_DEFAULTLISTENER | EVENT_HASDEFAULTHANDLERS | EVENT_BUBBLES | EVENT_CANCELABLE},
From: Gabriel Ivăncescu gabrielopcode@gmail.com
This simplifies the rest of the code.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 54 ++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 28 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index e1bac2400a9..cb2c6efb4c5 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -202,14 +202,17 @@ static const event_info_t event_info[] = { {L"timeout", EVENT_TYPE_PROGRESS, DISPID_EVPROP_TIMEOUT, EVENT_BIND_TO_TARGET}, {L"unload", EVENT_TYPE_UIEVENT, DISPID_EVMETH_ONUNLOAD, - EVENT_FIXME} + EVENT_FIXME}, + + /* EVENTID_LAST special entry */ + {NULL, EVENT_TYPE_EVENT, 0, 0} };
-C_ASSERT(ARRAY_SIZE(event_info) == EVENTID_LAST); +C_ASSERT(ARRAY_SIZE(event_info) - 1 == EVENTID_LAST);
static eventid_t str_to_eid(const WCHAR *str) { - unsigned i, a = 0, b = ARRAY_SIZE(event_info); + unsigned i, a = 0, b = ARRAY_SIZE(event_info) - 1; int c;
while(a < b) { @@ -225,7 +228,7 @@ static eventid_t str_to_eid(const WCHAR *str)
static eventid_t attr_to_eid(const WCHAR *str) { - unsigned i, a = 0, b = ARRAY_SIZE(event_info); + unsigned i, a = 0, b = ARRAY_SIZE(event_info) - 1; int c;
if((str[0] != 'o' && str[0] != 'O') || (str[1] != 'n' && str[1] != 'N')) @@ -262,7 +265,7 @@ static listener_container_t *get_listener_container(EventTarget *event_target, c return NULL;
eid = str_to_eid(type); - if(eid != EVENTID_LAST && (event_info[eid].flags & EVENT_FIXME)) + if(event_info[eid].flags & EVENT_FIXME) FIXME("unimplemented event %s\n", debugstr_w(event_info[eid].name));
type_len = lstrlenW(type); @@ -1687,18 +1690,16 @@ static HRESULT WINAPI DOMMouseEvent_get_fromElement(IDOMMouseEvent *iface, IHTML DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); eventid_t event_id = This->ui_event.event.event_id; IEventTarget *related_target = NULL; + HRESULT hres = S_OK;
TRACE("(%p)->(%p)\n", This, p);
- if(event_id != EVENTID_LAST) { - HRESULT hres = S_OK; - if(event_info[event_id].flags & EVENT_MOUSE_FROM_RELATED) - hres = IDOMMouseEvent_get_relatedTarget(&This->IDOMMouseEvent_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; - } + if(event_info[event_id].flags & EVENT_MOUSE_FROM_RELATED) + hres = IDOMMouseEvent_get_relatedTarget(&This->IDOMMouseEvent_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;
if(!related_target) { *p = NULL; @@ -1714,18 +1715,16 @@ static HRESULT WINAPI DOMMouseEvent_get_toElement(IDOMMouseEvent *iface, IHTMLEl DOMMouseEvent *This = impl_from_IDOMMouseEvent(iface); eventid_t event_id = This->ui_event.event.event_id; IEventTarget *related_target = NULL; + HRESULT hres = S_OK;
TRACE("(%p)->(%p)\n", This, p);
- if(event_id != EVENTID_LAST) { - HRESULT hres = S_OK; - if(event_info[event_id].flags & EVENT_MOUSE_TO_RELATED) - hres = IDOMMouseEvent_get_relatedTarget(&This->IDOMMouseEvent_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; - } + if(event_info[event_id].flags & EVENT_MOUSE_TO_RELATED) + hres = IDOMMouseEvent_get_relatedTarget(&This->IDOMMouseEvent_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;
if(!related_target) { *p = NULL; @@ -3393,9 +3392,8 @@ static void call_event_handlers(EventTarget *event_target, DOMEvent *event, disp if(listeners != listeners_buf) heap_free(listeners);
- if(event->phase != DEP_CAPTURING_PHASE && event->event_id != EVENTID_LAST - && event_info[event->event_id].dispid && (vtbl = dispex_get_vtbl(&event_target->dispex)) - && vtbl->get_cp_container) + if(event->phase != DEP_CAPTURING_PHASE && event_info[event->event_id].dispid + && (vtbl = dispex_get_vtbl(&event_target->dispex)) && vtbl->get_cp_container) cp_container = vtbl->get_cp_container(&event_target->dispex); if(cp_container) { if(cp_container->cps) { @@ -3533,7 +3531,7 @@ static HRESULT dispatch_event_object(EventTarget *event_target, DOMEvent *event, IHTMLEventObj_Release(prev_event); }
- if(event->event_id != EVENTID_LAST && (event_info[event->event_id].flags & EVENT_HASDEFAULTHANDLERS)) { + if(event_info[event->event_id].flags & EVENT_HASDEFAULTHANDLERS) { BOOL prevent_default = event->prevent_default; for(i = 0; !prevent_default && i < chain_cnt; i++) { vtbl = dispex_get_vtbl(&target_chain[i]->dispex); @@ -3571,7 +3569,7 @@ void dispatch_event(EventTarget *event_target, DOMEvent *event) * but we already dispatched event to all relevant targets. Stop event * propagation here to avoid events being dispatched multiple times. */ - if(event->event_id != EVENTID_LAST && (event_info[event->event_id].flags & EVENT_BIND_TO_TARGET)) + if(event_info[event->event_id].flags & EVENT_BIND_TO_TARGET) nsIDOMEvent_StopPropagation(event->nsevent); }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
The reason for the re-ordering in event types is due to querying the IIDs, where the order matters (MouseEvent must be queried before UIEvent, for example).
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 104 +++++++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 39 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index cb2c6efb4c5..581d949a447 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -59,13 +59,15 @@ typedef enum { DISPATCH_LEGACY } dispatch_mode_t;
+/* Keep inherited event types after the inheritor (e.g. DragEvent->MouseEvent->UIEvent) */ typedef enum { EVENT_TYPE_EVENT, - EVENT_TYPE_UIEVENT, + EVENT_TYPE_CUSTOM, + EVENT_TYPE_DRAG, EVENT_TYPE_KEYBOARD, EVENT_TYPE_MOUSE, EVENT_TYPE_FOCUS, - EVENT_TYPE_DRAG, + EVENT_TYPE_UIEVENT, EVENT_TYPE_MESSAGE, EVENT_TYPE_PROGRESS, EVENT_TYPE_STORAGE, @@ -74,11 +76,12 @@ typedef enum {
static const WCHAR *event_types[] = { L"Event", - L"UIEvent", + L"CustomEvent", + L"Event", /* FIXME */ L"KeyboardEvent", L"MouseEvent", L"Event", /* FIXME */ - L"Event", /* FIXME */ + L"UIEvent", L"MessageEvent", L"ProgressEvent", L"StorageEvent", @@ -2916,6 +2919,11 @@ static void fill_parent_ui_event(nsIDOMEvent *nsevent, DOMUIEvent *ui_event) nsIDOMEvent_QueryInterface(nsevent, &IID_nsIDOMUIEvent, (void**)&ui_event->nsevent); }
+static DOMEvent *generic_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, compat_mode_t compat_mode) +{ + return event_ctor(sizeof(DOMEvent), &DOMEvent_dispex, NULL, NULL, nsevent, event_id, compat_mode); +} + static DOMEvent *ui_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, compat_mode_t compat_mode) { DOMUIEvent *ui_event = event_ctor(sizeof(DOMUIEvent), &DOMUIEvent_dispex, @@ -2973,7 +2981,7 @@ static DOMEvent *progress_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_ return &progress_event->event; }
-static DOMEvent *message_event_ctor(nsIDOMEvent *nsevent, eventid_t event_id, compat_mode_t compat_mode) +static DOMEvent *message_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, compat_mode_t compat_mode) { DOMMessageEvent *message_event = event_ctor(sizeof(DOMMessageEvent), &DOMMessageEvent_dispex, DOMMessageEvent_query_interface, DOMMessageEvent_destroy, nsevent, event_id, compat_mode); @@ -2982,7 +2990,7 @@ static DOMEvent *message_event_ctor(nsIDOMEvent *nsevent, eventid_t event_id, co return &message_event->event; }
-static DOMEvent *storage_event_ctor(nsIDOMEvent *nsevent, eventid_t event_id, compat_mode_t compat_mode) +static DOMEvent *storage_event_ctor(void *iface, nsIDOMEvent *nsevent, eventid_t event_id, compat_mode_t compat_mode) { DOMStorageEvent *storage_event = event_ctor(sizeof(DOMStorageEvent), &DOMStorageEvent_dispex, DOMStorageEvent_query_interface, DOMStorageEvent_destroy, nsevent, event_id, compat_mode); @@ -2991,48 +2999,46 @@ static DOMEvent *storage_event_ctor(nsIDOMEvent *nsevent, eventid_t event_id, co return &storage_event->event; }
-static DOMEvent *alloc_event(nsIDOMEvent *nsevent, compat_mode_t compat_mode, eventid_t event_id) +static const struct { + REFIID iid; + DOMEvent *(*ctor)(void *iface, nsIDOMEvent *nsevent, eventid_t, compat_mode_t); +} event_types_ctor_table[] = { + [EVENT_TYPE_EVENT] = { NULL, generic_event_ctor }, + [EVENT_TYPE_UIEVENT] = { &IID_nsIDOMUIEvent, ui_event_ctor }, + [EVENT_TYPE_MOUSE] = { &IID_nsIDOMMouseEvent, mouse_event_ctor }, + [EVENT_TYPE_KEYBOARD] = { &IID_nsIDOMKeyEvent, keyboard_event_ctor }, + [EVENT_TYPE_CLIPBOARD] = { NULL, generic_event_ctor }, + [EVENT_TYPE_FOCUS] = { NULL, generic_event_ctor }, + [EVENT_TYPE_DRAG] = { NULL, generic_event_ctor }, + [EVENT_TYPE_CUSTOM] = { &IID_nsIDOMCustomEvent, custom_event_ctor }, + [EVENT_TYPE_PROGRESS] = { &IID_nsIDOMProgressEvent, progress_event_ctor }, + [EVENT_TYPE_MESSAGE] = { NULL, message_event_ctor }, + [EVENT_TYPE_STORAGE] = { NULL, storage_event_ctor }, +}; + +static DOMEvent *alloc_event(nsIDOMEvent *nsevent, compat_mode_t compat_mode, event_type_t event_type, + eventid_t event_id) { - static const struct { - REFIID iid; - DOMEvent *(*ctor)(void *iface, nsIDOMEvent *nsevent, eventid_t, compat_mode_t); - } types_table[] = { - { &IID_nsIDOMMouseEvent, mouse_event_ctor }, - { &IID_nsIDOMKeyEvent, keyboard_event_ctor }, - { &IID_nsIDOMUIEvent, ui_event_ctor }, - { &IID_nsIDOMCustomEvent, custom_event_ctor }, - { &IID_nsIDOMProgressEvent, progress_event_ctor }, - }; + void *iface = NULL; DOMEvent *event; - unsigned i; - - switch(event_id) { - case EVENTID_MESSAGE: return message_event_ctor(nsevent, event_id, compat_mode); - case EVENTID_STORAGECOMMIT: - case EVENTID_STORAGE: return storage_event_ctor(nsevent, event_id, compat_mode); - default: break; - }
- for(i = 0; i < ARRAY_SIZE(types_table); i++) { - void *iface; - nsresult 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, nsevent, event_id, compat_mode))) - nsISupports_Release(iface); - return event; - } - } + if(event_types_ctor_table[event_type].iid) + nsIDOMEvent_QueryInterface(nsevent, event_types_ctor_table[event_type].iid, &iface);
- return event_ctor(sizeof(DOMEvent), &DOMEvent_dispex, NULL, NULL, nsevent, event_id, compat_mode); + /* Transfer the iface ownership to the ctor on success */ + if(!(event = event_types_ctor_table[event_type].ctor(iface, nsevent, event_id, compat_mode)) && iface) + nsISupports_Release(iface); + return event; }
HRESULT create_event_from_nsevent(nsIDOMEvent *nsevent, compat_mode_t compat_mode, DOMEvent **ret_event) { + event_type_t event_type = EVENT_TYPE_EVENT; eventid_t event_id = EVENTID_LAST; DOMEvent *event; nsAString nsstr; nsresult nsres; + unsigned i;
nsAString_Init(&nsstr, NULL); nsres = nsIDOMEvent_GetType(nsevent, &nsstr); @@ -3047,7 +3053,17 @@ HRESULT create_event_from_nsevent(nsIDOMEvent *nsevent, compat_mode_t compat_mod } nsAString_Finish(&nsstr);
- event = alloc_event(nsevent, compat_mode, event_id); + for(i = 0; i < ARRAY_SIZE(event_types_ctor_table); i++) { + void *iface; + if(event_types_ctor_table[i].iid && + nsIDOMEvent_QueryInterface(nsevent, event_types_ctor_table[i].iid, &iface) == NS_OK) { + nsISupports_Release(iface); + event_type = i; + break; + } + } + + event = alloc_event(nsevent, compat_mode, event_type, event_id); if(!event) return E_OUTOFMEMORY;
@@ -3058,10 +3074,12 @@ HRESULT create_event_from_nsevent(nsIDOMEvent *nsevent, compat_mode_t compat_mod
HRESULT create_document_event_str(HTMLDocumentNode *doc, const WCHAR *type, IDOMEvent **ret_event) { + event_type_t event_type = EVENT_TYPE_EVENT; nsIDOMEvent *nsevent; DOMEvent *event; nsAString nsstr; nsresult nsres; + unsigned i;
nsAString_InitDepend(&nsstr, type); nsres = nsIDOMHTMLDocument_CreateEvent(doc->nsdoc, &nsstr, &nsevent); @@ -3071,7 +3089,15 @@ HRESULT create_document_event_str(HTMLDocumentNode *doc, const WCHAR *type, IDOM return E_FAIL; }
- event = alloc_event(nsevent, dispex_compat_mode(&doc->node.event_target.dispex), EVENTID_LAST); + for(i = 0; i < ARRAY_SIZE(event_types); i++) { + if(!wcsicmp(type, event_types[i])) { + event_type = i; + break; + } + } + + event = alloc_event(nsevent, dispex_compat_mode(&doc->node.event_target.dispex), + event_type, EVENTID_LAST); nsIDOMEvent_Release(nsevent); if(!event) return E_OUTOFMEMORY; @@ -3095,7 +3121,7 @@ HRESULT create_document_event(HTMLDocumentNode *doc, eventid_t event_id, DOMEven return E_FAIL; }
- event = alloc_event(nsevent, doc->document_mode, event_id); + event = alloc_event(nsevent, doc->document_mode, event_info[event_id].type, event_id); if(!event) return E_OUTOFMEMORY;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index ba631c9a7ef..02d6d374255 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3243,7 +3243,7 @@ static HRESULT WINAPI window_private_postMessage(IWineHTMLWindowPrivate *iface, TRACE("iface %p, msg %s, targetOrigin %s, transfer %s\n", iface, debugstr_variant(&msg), debugstr_w(targetOrigin), debugstr_variant(&transfer));
- if(V_VT(&transfer) != VT_EMPTY) + if(V_VT(&transfer) != VT_EMPTY && V_VT(&transfer) != VT_ERROR) FIXME("transfer not implemented, ignoring\n");
hres = check_target_origin(window, targetOrigin);
This merge request was approved by Jacek Caban.