From: Gabriel Ivăncescu gabrielopcode@gmail.com
Otherwise, script56.chm's javascript will keep reloading the image and triggering onload events non-stop. It protects against this using a variable "noReentry", which is only set temporarily while setting the source, so it expects it to be triggered synchronously.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53927 Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
wine-gecko always sends them asynchronously, which is the same behavior as IE9+ modes. See dom/base/nsImageLoadingContent.cpp: nsImageLoadingContent::FireEvent. The comment there, funnily enough, is what script56.chm's script protects against (and breaks because of async behavior). --- dlls/mshtml/htmlanchor.c | 1 + dlls/mshtml/htmlarea.c | 1 + dlls/mshtml/htmlbody.c | 1 + dlls/mshtml/htmlcomment.c | 1 + dlls/mshtml/htmldoc.c | 3 ++ dlls/mshtml/htmlelem.c | 13 +++++++++ dlls/mshtml/htmlevent.h | 2 ++ dlls/mshtml/htmlform.c | 1 + dlls/mshtml/htmlframe.c | 2 ++ dlls/mshtml/htmlgeneric.c | 1 + dlls/mshtml/htmlhead.c | 4 +++ dlls/mshtml/htmlimg.c | 40 +++++++++++++++++++++++++- dlls/mshtml/htmlinput.c | 3 ++ dlls/mshtml/htmllink.c | 1 + dlls/mshtml/htmlobject.c | 2 ++ dlls/mshtml/htmlscript.c | 1 + dlls/mshtml/htmlselect.c | 2 ++ dlls/mshtml/htmlstyleelem.c | 1 + dlls/mshtml/htmltable.c | 3 ++ dlls/mshtml/htmltextarea.c | 1 + dlls/mshtml/htmlwindow.c | 1 + dlls/mshtml/mshtml_private.h | 3 ++ dlls/mshtml/nsevents.c | 11 +++++++- dlls/mshtml/svg.c | 4 +++ dlls/mshtml/tests/events.c | 54 ++++++++++++++++++++++++++++++++---- 25 files changed, 149 insertions(+), 8 deletions(-)
diff --git a/dlls/mshtml/htmlanchor.c b/dlls/mshtml/htmlanchor.c index 1e783ce007e..f4c0ff88c6d 100644 --- a/dlls/mshtml/htmlanchor.c +++ b/dlls/mshtml/htmlanchor.c @@ -879,6 +879,7 @@ static const NodeImplVtbl HTMLAnchorElementImplVtbl = { HTMLElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLAnchorElement_handle_event, HTMLElement_get_attr_col, NULL, diff --git a/dlls/mshtml/htmlarea.c b/dlls/mshtml/htmlarea.c index eb7ea383db9..18736b1fd21 100644 --- a/dlls/mshtml/htmlarea.c +++ b/dlls/mshtml/htmlarea.c @@ -467,6 +467,7 @@ static const NodeImplVtbl HTMLAreaElementImplVtbl = { HTMLElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLAreaElement_handle_event, HTMLElement_get_attr_col }; diff --git a/dlls/mshtml/htmlbody.c b/dlls/mshtml/htmlbody.c index 6338e7e907b..311bbca2257 100644 --- a/dlls/mshtml/htmlbody.c +++ b/dlls/mshtml/htmlbody.c @@ -983,6 +983,7 @@ static const NodeImplVtbl HTMLBodyElementImplVtbl = { HTMLElement_destructor, HTMLBodyElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col, HTMLBodyElement_get_event_prop_target, diff --git a/dlls/mshtml/htmlcomment.c b/dlls/mshtml/htmlcomment.c index cc3bec32959..dd4c83cc77c 100644 --- a/dlls/mshtml/htmlcomment.c +++ b/dlls/mshtml/htmlcomment.c @@ -189,6 +189,7 @@ static const NodeImplVtbl HTMLCommentElementImplVtbl = { HTMLCommentElement_destructor, HTMLElement_cpc, HTMLCommentElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col }; diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index a80dfe4f671..49640cff9da 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -371,6 +371,7 @@ static event_target_vtbl_t DocumentType_event_target_vtbl = { }, DocumentType_get_gecko_target, NULL, + NULL, DocumentType_get_parent_event_target, NULL, NULL, @@ -5915,6 +5916,7 @@ static const NodeImplVtbl HTMLDocumentNodeImplVtbl = { NULL, NULL, NULL, + NULL, HTMLDocumentNode_traverse, HTMLDocumentNode_unlink }; @@ -6120,6 +6122,7 @@ static const event_target_vtbl_t HTMLDocumentNode_event_target_vtbl = { }, HTMLDocumentNode_get_gecko_target, HTMLDocumentNode_bind_event, + NULL, HTMLDocumentNode_get_parent_event_target, NULL, HTMLDocumentNode_get_cp_container, diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index 07fe6141e6b..b66b0c22552 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -6765,6 +6765,11 @@ HRESULT HTMLElement_clone(HTMLDOMNode *iface, nsIDOMNode *nsnode, HTMLDOMNode ** return S_OK; }
+HRESULT HTMLElement_dispatch_nsevent_hook(HTMLDOMNode *iface, DOMEvent *event) +{ + return S_FALSE; +} + HRESULT HTMLElement_handle_event(HTMLDOMNode *iface, DWORD eid, nsIDOMEvent *event, BOOL *prevent_default) { HTMLElement *This = impl_from_HTMLDOMNode(iface); @@ -6815,6 +6820,7 @@ static const NodeImplVtbl HTMLElementImplVtbl = { HTMLElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col }; @@ -6957,6 +6963,12 @@ static void HTMLElement_bind_event(DispatchEx *dispex, eventid_t eid) ensure_doc_nsevent_handler(This->node.doc, This->node.nsnode, eid); }
+static HRESULT HTMLElement_event_target_dispatch_nsevent_hook(DispatchEx *dispex, DOMEvent *event) +{ + HTMLElement *This = impl_from_DispatchEx(dispex); + return This->node.vtbl->dispatch_nsevent_hook(&This->node, event); +} + static HRESULT HTMLElement_handle_event_default(DispatchEx *dispex, eventid_t eid, nsIDOMEvent *nsevent, BOOL *prevent_default) { HTMLElement *This = impl_from_DispatchEx(dispex); @@ -7230,6 +7242,7 @@ static event_target_vtbl_t HTMLElement_event_target_vtbl = { }, HTMLElement_get_gecko_target, HTMLElement_bind_event, + HTMLElement_event_target_dispatch_nsevent_hook, HTMLElement_get_parent_event_target, HTMLElement_handle_event_default, HTMLElement_get_cp_container, diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index 104cb8554d2..70dbb1890b4 100644 --- a/dlls/mshtml/htmlevent.h +++ b/dlls/mshtml/htmlevent.h @@ -17,6 +17,7 @@ */
typedef enum { + EVENTID_INVALID = -1, EVENTID_DOMCONTENTLOADED, EVENTID_ABORT, EVENTID_AFTERPRINT, @@ -131,6 +132,7 @@ typedef struct { dispex_static_data_vtbl_t dispex_vtbl; nsISupports *(*get_gecko_target)(DispatchEx*); void (*bind_event)(DispatchEx*,eventid_t); + HRESULT (*dispatch_nsevent_hook)(DispatchEx*,DOMEvent*); EventTarget *(*get_parent_event_target)(DispatchEx*); HRESULT (*handle_event_default)(DispatchEx*,eventid_t,nsIDOMEvent*,BOOL*); ConnectionPointContainer *(*get_cp_container)(DispatchEx*); diff --git a/dlls/mshtml/htmlform.c b/dlls/mshtml/htmlform.c index 3e7ca112311..8a15bbf307d 100644 --- a/dlls/mshtml/htmlform.c +++ b/dlls/mshtml/htmlform.c @@ -984,6 +984,7 @@ static const NodeImplVtbl HTMLFormElementImplVtbl = { HTMLElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLFormElement_handle_event, HTMLElement_get_attr_col, NULL, diff --git a/dlls/mshtml/htmlframe.c b/dlls/mshtml/htmlframe.c index ffd8156a9ef..e1b1562b0dc 100644 --- a/dlls/mshtml/htmlframe.c +++ b/dlls/mshtml/htmlframe.c @@ -1013,6 +1013,7 @@ static const NodeImplVtbl HTMLFrameElementImplVtbl = { HTMLFrameElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col, NULL, @@ -1606,6 +1607,7 @@ static const NodeImplVtbl HTMLIFrameImplVtbl = { HTMLIFrame_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col, NULL, diff --git a/dlls/mshtml/htmlgeneric.c b/dlls/mshtml/htmlgeneric.c index 9244ba017fb..27632f74624 100644 --- a/dlls/mshtml/htmlgeneric.c +++ b/dlls/mshtml/htmlgeneric.c @@ -157,6 +157,7 @@ static const NodeImplVtbl HTMLGenericElementImplVtbl = { HTMLGenericElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col }; diff --git a/dlls/mshtml/htmlhead.c b/dlls/mshtml/htmlhead.c index 072efd967b9..423bc355f1b 100644 --- a/dlls/mshtml/htmlhead.c +++ b/dlls/mshtml/htmlhead.c @@ -173,6 +173,7 @@ static const NodeImplVtbl HTMLTitleElementImplVtbl = { HTMLTitleElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col }; @@ -345,6 +346,7 @@ static const NodeImplVtbl HTMLHtmlElementImplVtbl = { HTMLHtmlElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col, NULL, @@ -594,6 +596,7 @@ static const NodeImplVtbl HTMLMetaElementImplVtbl = { HTMLMetaElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col }; @@ -759,6 +762,7 @@ static const NodeImplVtbl HTMLHeadElementImplVtbl = { HTMLHeadElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col }; diff --git a/dlls/mshtml/htmlimg.c b/dlls/mshtml/htmlimg.c index 713cb157512..d8c377413f0 100644 --- a/dlls/mshtml/htmlimg.c +++ b/dlls/mshtml/htmlimg.c @@ -39,6 +39,7 @@ struct HTMLImg { IHTMLImgElement IHTMLImgElement_iface;
nsIDOMHTMLImageElement *nsimg; + eventid_t skip_event; };
static inline HTMLImg *impl_from_IHTMLImgElement(IHTMLImgElement *iface) @@ -281,6 +282,7 @@ static HRESULT WINAPI HTMLImgElement_get_alt(IHTMLImgElement *iface, BSTR *p) static HRESULT WINAPI HTMLImgElement_put_src(IHTMLImgElement *iface, BSTR v) { HTMLImg *This = impl_from_IHTMLImgElement(iface); + HRESULT hres = S_OK; nsAString src_str; nsresult nsres;
@@ -292,7 +294,29 @@ static HRESULT WINAPI HTMLImgElement_put_src(IHTMLImgElement *iface, BSTR v) if(NS_FAILED(nsres)) ERR("SetSrc failed: %08lx\n", nsres);
- return S_OK; + if(dispex_compat_mode(&This->element.node.event_target.dispex) < COMPAT_MODE_IE9) { + eventid_t eventid; + cpp_bool complete; + UINT32 height = 0; + DOMEvent *event; + + /* Synchronously send load event if the image was completed immediately (such as from cache) */ + This->skip_event = EVENTID_INVALID; + + nsres = nsIDOMHTMLImageElement_GetComplete(This->nsimg, &complete); + if(NS_SUCCEEDED(nsres) && complete) { + nsIDOMHTMLImageElement_GetNaturalHeight(This->nsimg, &height); + eventid = height ? EVENTID_LOAD : EVENTID_ERROR; + + hres = create_document_event(This->element.node.doc, eventid, &event); + if(SUCCEEDED(hres)) { + This->skip_event = eventid; + dispatch_event(&This->element.node.event_target, event); + IDOMEvent_Release(&event->IDOMEvent_iface); + } + } + } + return hres; }
static HRESULT WINAPI HTMLImgElement_get_src(IHTMLImgElement *iface, BSTR *p) @@ -678,6 +702,18 @@ static HRESULT HTMLImgElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv) return S_OK; }
+static HRESULT HTMLImgElement_dispatch_nsevent_hook(HTMLDOMNode *iface, DOMEvent *event) +{ + HTMLImg *This = impl_from_HTMLDOMNode(iface); + + if(event->event_id == This->skip_event) { + This->skip_event = EVENTID_INVALID; + return S_OK; + } + + return S_FALSE; +} + static HRESULT HTMLImgElement_get_readystate(HTMLDOMNode *iface, BSTR *p) { HTMLImg *This = impl_from_HTMLDOMNode(iface); @@ -711,6 +747,7 @@ static const NodeImplVtbl HTMLImgElementImplVtbl = { HTMLElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLImgElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col, NULL, @@ -762,6 +799,7 @@ HRESULT HTMLImgElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTML
ret->IHTMLImgElement_iface.lpVtbl = &HTMLImgElementVtbl; ret->element.node.vtbl = &HTMLImgElementImplVtbl; + ret->skip_event = EVENTID_INVALID;
HTMLElement_Init(&ret->element, doc, nselem, &HTMLImgElement_dispex);
diff --git a/dlls/mshtml/htmlinput.c b/dlls/mshtml/htmlinput.c index 7a3dc848f7d..e02ac2249d9 100644 --- a/dlls/mshtml/htmlinput.c +++ b/dlls/mshtml/htmlinput.c @@ -1423,6 +1423,7 @@ static const NodeImplVtbl HTMLInputElementImplVtbl = { HTMLElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col, NULL, @@ -1632,6 +1633,7 @@ static const NodeImplVtbl HTMLLabelElementImplVtbl = { HTMLElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col, }; @@ -1968,6 +1970,7 @@ static const NodeImplVtbl HTMLButtonElementImplVtbl = { HTMLElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col, NULL, diff --git a/dlls/mshtml/htmllink.c b/dlls/mshtml/htmllink.c index 124507a2fc9..a491cabae02 100644 --- a/dlls/mshtml/htmllink.c +++ b/dlls/mshtml/htmllink.c @@ -426,6 +426,7 @@ static const NodeImplVtbl HTMLLinkElementImplVtbl = { HTMLElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col, NULL, diff --git a/dlls/mshtml/htmlobject.c b/dlls/mshtml/htmlobject.c index 9e30b5426fb..60746562692 100644 --- a/dlls/mshtml/htmlobject.c +++ b/dlls/mshtml/htmlobject.c @@ -754,6 +754,7 @@ static const NodeImplVtbl HTMLObjectElementImplVtbl = { HTMLObjectElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col, NULL, @@ -1029,6 +1030,7 @@ static const NodeImplVtbl HTMLEmbedElementImplVtbl = { HTMLEmbedElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col }; diff --git a/dlls/mshtml/htmlscript.c b/dlls/mshtml/htmlscript.c index 2ef21fbfb0a..e2ca3fb9b2a 100644 --- a/dlls/mshtml/htmlscript.c +++ b/dlls/mshtml/htmlscript.c @@ -438,6 +438,7 @@ static const NodeImplVtbl HTMLScriptElementImplVtbl = { HTMLScriptElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col, NULL, diff --git a/dlls/mshtml/htmlselect.c b/dlls/mshtml/htmlselect.c index f0ebfd16d11..4dfbbd916a7 100644 --- a/dlls/mshtml/htmlselect.c +++ b/dlls/mshtml/htmlselect.c @@ -396,6 +396,7 @@ static const NodeImplVtbl HTMLOptionElementImplVtbl = { HTMLElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col, NULL, @@ -1473,6 +1474,7 @@ static const NodeImplVtbl HTMLSelectElementImplVtbl = { HTMLElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col, NULL, diff --git a/dlls/mshtml/htmlstyleelem.c b/dlls/mshtml/htmlstyleelem.c index abd720cc18f..d0465d1495a 100644 --- a/dlls/mshtml/htmlstyleelem.c +++ b/dlls/mshtml/htmlstyleelem.c @@ -443,6 +443,7 @@ static const NodeImplVtbl HTMLStyleElementImplVtbl = { HTMLStyleElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col, NULL, diff --git a/dlls/mshtml/htmltable.c b/dlls/mshtml/htmltable.c index 1afb32ea6ec..df2cb92b8c9 100644 --- a/dlls/mshtml/htmltable.c +++ b/dlls/mshtml/htmltable.c @@ -499,6 +499,7 @@ static const NodeImplVtbl HTMLTableCellImplVtbl = { HTMLTableCell_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col, NULL, @@ -945,6 +946,7 @@ static const NodeImplVtbl HTMLTableRowImplVtbl = { HTMLElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col, NULL, @@ -1977,6 +1979,7 @@ static const NodeImplVtbl HTMLTableImplVtbl = { HTMLElement_destructor, HTMLTable_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col, NULL, diff --git a/dlls/mshtml/htmltextarea.c b/dlls/mshtml/htmltextarea.c index 5820c0c7291..8e6f931c635 100644 --- a/dlls/mshtml/htmltextarea.c +++ b/dlls/mshtml/htmltextarea.c @@ -457,6 +457,7 @@ static const NodeImplVtbl HTMLTextAreaElementImplVtbl = { HTMLElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, HTMLElement_handle_event, HTMLElement_get_attr_col, NULL, diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index bc3908b8d4c..732f5ec7316 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -4011,6 +4011,7 @@ static const event_target_vtbl_t HTMLWindow_event_target_vtbl = { NULL, NULL, NULL, + NULL, HTMLWindow_set_current_event };
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index b750cad6585..a648cb12be8 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -76,6 +76,7 @@ #define MSHTML_E_INVALID_ACTION 0x800a01bd #define MSHTML_E_NODOC 0x800a025c
+typedef struct DOMEvent DOMEvent; typedef struct HTMLDOMNode HTMLDOMNode; typedef struct ConnectionPoint ConnectionPoint; typedef struct BSCallback BSCallback; @@ -806,6 +807,7 @@ typedef struct { void (*destructor)(HTMLDOMNode*); const cpc_entry_t *cpc_entries; HRESULT (*clone)(HTMLDOMNode*,nsIDOMNode*,HTMLDOMNode**); + HRESULT (*dispatch_nsevent_hook)(HTMLDOMNode*,DOMEvent*); HRESULT (*handle_event)(HTMLDOMNode*,DWORD,nsIDOMEvent*,BOOL*); HRESULT (*get_attr_col)(HTMLDOMNode*,HTMLAttributeCollection**); EventTarget *(*get_event_prop_target)(HTMLDOMNode*,int); @@ -1209,6 +1211,7 @@ HRESULT HTMLElement_QI(HTMLDOMNode*,REFIID,void**) DECLSPEC_HIDDEN; void HTMLElement_destructor(HTMLDOMNode*) DECLSPEC_HIDDEN; HRESULT HTMLElement_clone(HTMLDOMNode*,nsIDOMNode*,HTMLDOMNode**) DECLSPEC_HIDDEN; HRESULT HTMLElement_get_attr_col(HTMLDOMNode*,HTMLAttributeCollection**) DECLSPEC_HIDDEN; +HRESULT HTMLElement_dispatch_nsevent_hook(HTMLDOMNode*,DOMEvent*) DECLSPEC_HIDDEN; HRESULT HTMLElement_handle_event(HTMLDOMNode*,DWORD,nsIDOMEvent*,BOOL*) DECLSPEC_HIDDEN; void HTMLElement_init_dispex_info(dispex_data_t*,compat_mode_t) DECLSPEC_HIDDEN;
diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index f15e57df38d..c9ded470cd8 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -446,6 +446,7 @@ static nsresult NSAPI handle_htmlevent(nsIDOMEventListener *iface, nsIDOMEvent * { nsEventListener *This = impl_from_nsIDOMEventListener(iface); HTMLDocumentNode *doc = This->This->doc; + const event_target_vtbl_t *target_vtbl; nsIDOMEventTarget *event_target; EventTarget *target; nsIDOMNode *nsnode; @@ -499,7 +500,15 @@ static nsresult NSAPI handle_htmlevent(nsIDOMEventListener *iface, nsIDOMEvent * } }
- dispatch_event(target, event); + target_vtbl = dispex_get_vtbl(&target->dispex); + + if(target_vtbl && target_vtbl->dispatch_nsevent_hook && + target_vtbl->dispatch_nsevent_hook(&target->dispex, event) == S_OK) { + /* overridden by hook, so cancel it */ + nsIDOMEvent_StopPropagation(nsevent); + }else { + dispatch_event(target, event); + }
IDOMEvent_Release(&event->IDOMEvent_iface); IEventTarget_Release(&target->IEventTarget_iface); diff --git a/dlls/mshtml/svg.c b/dlls/mshtml/svg.c index b03ad073244..718a39a328c 100644 --- a/dlls/mshtml/svg.c +++ b/dlls/mshtml/svg.c @@ -198,6 +198,7 @@ static const NodeImplVtbl SVGElementImplVtbl = { HTMLElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, NULL, HTMLElement_get_attr_col, }; @@ -739,6 +740,7 @@ static const NodeImplVtbl SVGSVGElementImplVtbl = { HTMLElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, NULL, HTMLElement_get_attr_col, }; @@ -908,6 +910,7 @@ static const NodeImplVtbl SVGCircleElementImplVtbl = { HTMLElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, NULL, HTMLElement_get_attr_col, }; @@ -1152,6 +1155,7 @@ static const NodeImplVtbl SVGTSpanElementImplVtbl = { HTMLElement_destructor, HTMLElement_cpc, HTMLElement_clone, + HTMLElement_dispatch_nsevent_hook, NULL, HTMLElement_get_attr_col, }; diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index e5ad840df7f..a231f9e631c 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -145,7 +145,12 @@ static const char readystate_doc_ie9_str[] = "<body><iframe id="iframe"></iframe></body></html>";
static const char img_doc_str[] = - "<html><body><img id="imgid"></img></body></html>"; + "<html><head><meta http-equiv="x-ua-compatible" content="IE=8" /></head>" + "<body><img id="imgid"></img></body></html>"; + +static const char img_doc_ie9_str[] = + "<html><head><meta http-equiv="x-ua-compatible" content="IE=9" /></head>" + "<body><img id="imgid"></img></body></html>";
static const char input_image_doc_str[] = "<html><body><input type="image" id="inputid"></input></body></html>"; @@ -1083,7 +1088,7 @@ static HRESULT WINAPI img_onload(IDispatchEx *iface, DISPID id, LCID lcid, WORD VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { CHECK_EXPECT(img_onload); - test_event_args(&DIID_DispHTMLImg, id, wFlags, pdp, pvarRes, pei, pspCaller); + test_event_args(document_mode < 9 ? &DIID_DispHTMLImg : NULL, id, wFlags, pdp, pvarRes, pei, pspCaller); test_event_src(L"IMG"); return S_OK; } @@ -1119,7 +1124,7 @@ static HRESULT WINAPI unattached_img_onload(IDispatchEx *iface, DISPID id, LCID
CHECK_EXPECT(img_onload);
- test_event_args(&DIID_DispHTMLImg, id, wFlags, pdp, pvarRes, pei, pspCaller); + test_event_args(document_mode < 9 ? &DIID_DispHTMLImg : NULL, id, wFlags, pdp, pvarRes, pei, pspCaller); event_src = get_event_src(); todo_wine ok(!event_src, "event_src != NULL\n"); @@ -1134,7 +1139,7 @@ static HRESULT WINAPI img_onerror(IDispatchEx *iface, DISPID id, LCID lcid, WORD VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { CHECK_EXPECT(img_onerror); - test_event_args(&DIID_DispHTMLImg, id, wFlags, pdp, pvarRes, pei, pspCaller); + test_event_args(document_mode < 9 ? &DIID_DispHTMLImg : NULL, id, wFlags, pdp, pvarRes, pei, pspCaller); test_event_src(L"IMG"); return S_OK; } @@ -2266,13 +2271,13 @@ static void test_imgload(IHTMLDocument2 *doc) { IHTMLImgElement *img; IHTMLElement *elem; + VARIANT_BOOL b; VARIANT v; BSTR str; HRESULT hres;
elem = get_elem_id(doc, L"imgid"); hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLImgElement, (void**)&img); - IHTMLElement_Release(elem); ok(hres == S_OK, "Could not get IHTMLImgElement iface: %08lx\n", hres);
V_VT(&v) = VT_EMPTY; @@ -2307,12 +2312,47 @@ static void test_imgload(IHTMLDocument2 *doc) str = SysAllocString(L"http://test.winehq.org/tests/winehq_snapshot/index_files/winehq_logo_text.pn..."); hres = IHTMLImgElement_put_src(img, str); ok(hres == S_OK, "put_src failed: %08lx\n", hres); - SysFreeString(str);
SET_EXPECT(img_onload); pump_msgs(&called_img_onload); CHECK_CALLED(img_onload);
+ hres = IHTMLImgElement_get_complete(img, &b); + ok(hres == S_OK, "get_complete failed: %08lx\n", hres); + ok(b == VARIANT_TRUE, "complete = %x\n", b); + + /* cached images send synchronous load event in legacy modes */ + if(document_mode < 9) + SET_EXPECT(img_onload); + hres = IHTMLImgElement_put_src(img, str); + ok(hres == S_OK, "put_src failed: %08lx\n", hres); + if(document_mode < 9) { + CHECK_CALLED(img_onload); + pump_msgs(NULL); + }else { + SET_EXPECT(img_onload); + pump_msgs(&called_img_onload); + CHECK_CALLED(img_onload); + } + + if(document_mode < 9) + SET_EXPECT(img_onload); + V_VT(&v) = VT_BSTR; + V_BSTR(&v) = str; + str = SysAllocString(L"src"); + hres = IHTMLElement_setAttribute(elem, str, v, 0); + ok(hres == S_OK, "setAttribute failed: %08lx\n", hres); + SysFreeString(str); + VariantClear(&v); + if(document_mode < 9) { + CHECK_CALLED(img_onload); + pump_msgs(NULL); + }else { + SET_EXPECT(img_onload); + pump_msgs(&called_img_onload); + CHECK_CALLED(img_onload); + } + SET_EXPECT(img_onerror);
str = SysAllocString(L"about:blank"); @@ -2325,6 +2365,7 @@ static void test_imgload(IHTMLDocument2 *doc) CHECK_CALLED(img_onerror);
IHTMLImgElement_Release(img); + IHTMLElement_Release(elem);
/* test onload on unattached image */ hres = IHTMLDocument2_createElement(doc, (str = SysAllocString(L"img")), &elem); @@ -5846,6 +5887,7 @@ START_TEST(events) run_test_from_res(L"blank_ie10.html", test_visibilitychange); run_test_from_res(L"iframe.html", test_unload_event); run_test(empty_doc_ie9_str, test_create_event); + run_test(img_doc_ie9_str, test_imgload); }
test_empty_document();