For the image load event patch, 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), but there's no way to selectively override it (because of compat mode), so we have to workaround it on mshtml side.
Note that we only hook the gecko events (nsevents) being dispatched, and that's obviously on purpose. We wouldn't want to skip a load event dispatched by some script or app's code.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53999 Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/nsevents.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index 875d2b5bcf6..f15e57df38d 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -343,6 +343,9 @@ static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event
IHTMLDOMNode_AddRef(&doc->node.IHTMLDOMNode_iface);
+ /* Keep a ref to the window as well, some apps navigate during the notifications */ + IHTMLWindow2_AddRef(&doc->window->base.IHTMLWindow2_iface); + if(doc_obj) handle_docobj_load(doc_obj);
@@ -382,6 +385,7 @@ static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event
doc->window->performance_timing->load_event_end_time = get_time_stamp();
+ IHTMLWindow2_Release(&doc->window->base.IHTMLWindow2_iface); IHTMLDOMNode_Release(&doc->node.IHTMLDOMNode_iface); return NS_OK; }
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();
From: Gabriel Ivăncescu gabrielopcode@gmail.com
For some reason, only pure js objects are passed in mshtml's jscript engine.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 11 ++--- dlls/mshtml/tests/es5.js | 14 +++++++ dlls/mshtml/tests/script.c | 83 +++++++++++++++++++++++++++++++++++++- 3 files changed, 100 insertions(+), 8 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 4e872c93717..1a7a75875df 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -2212,14 +2212,11 @@ HRESULT disp_call_value(script_ctx_t *ctx, IDispatch *disp, jsval_t vthis, WORD if(jsdisp) jsdisp_release(jsdisp);
- if(is_undefined(vthis)) - jsthis = NULL; - else if(is_object_instance(vthis)) + if(is_object_instance(vthis) && (ctx->version < SCRIPTLANGUAGEVERSION_ES5 || + ((jsdisp = to_jsdisp(get_object(vthis))) && is_class(jsdisp, JSCLASS_OBJECT)))) jsthis = get_object(vthis); - else { - FIXME("Unimplemented 'this' passed to host object: %s\n", debugstr_jsval(vthis)); - return E_NOTIMPL; - } + else + jsthis = NULL;
flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK; if(r && argc && flags == DISPATCH_METHOD) diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 93ede87eeb0..c74513a84fa 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -1668,6 +1668,20 @@ sync_test("builtin_context", function() { ok(obj.valueOf() === 42, "obj = " + obj); });
+sync_test("host this", function() { + var tests = [ undefined, null, external.nullDisp, function() {}, [0], "foobar", true, 42, new Number(42), external.testHostContext, window, document ]; + var i, obj = Object.create(Function.prototype); + + // only pure js objects are passed as 'this' (regardless of prototype) + [137].forEach(external.testHostContext(true), obj); + Function.prototype.apply.call(external.testHostContext(true), obj, [137, 0, {}]); + + for(i = 0; i < tests.length; i++) { + [137].forEach(external.testHostContext(false), tests[i]); + Function.prototype.apply.call(external.testHostContext(false), tests[i], [137, 0, {}]); + } +}); + sync_test("head_setter", function() { document.head = ""; ok(typeof(document.head) === "object", "typeof(document.head) = " + typeof(document.head)); diff --git a/dlls/mshtml/tests/script.c b/dlls/mshtml/tests/script.c index b27b68b5bd1..d5335f1d2c1 100644 --- a/dlls/mshtml/tests/script.c +++ b/dlls/mshtml/tests/script.c @@ -158,7 +158,8 @@ DEFINE_EXPECT(GetTypeInfo); #define DISPID_EXTERNAL_IS_ENGLISH 0x300009 #define DISPID_EXTERNAL_LIST_SEP 0x30000A #define DISPID_EXTERNAL_TEST_VARS 0x30000B -#define DISPID_EXTERNAL_GETMIMETYPE 0x30000C +#define DISPID_EXTERNAL_TESTHOSTCTX 0x30000C +#define DISPID_EXTERNAL_GETMIMETYPE 0x30000D
static const GUID CLSID_TestScript = {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x07,0x46}}; @@ -745,6 +746,62 @@ static IDispatchExVtbl scriptDispVtbl = {
static IDispatchEx scriptDisp = { &scriptDispVtbl };
+static BOOL testHostContextDisp_expect; +static HRESULT WINAPI testHostContextDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + ok(id == DISPID_VALUE, "id = %ld\n", id); + ok(wFlags == (DISPATCH_PROPERTYGET | DISPATCH_METHOD), "wFlags = %x\n", wFlags); + ok(pdp != NULL, "pdp == NULL\n"); + if(testHostContextDisp_expect) { + ok(pdp->cArgs == 4, "pdp->cArgs = %d\n", pdp->cArgs); + ok(pdp->cNamedArgs == 1, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs); + ok(pdp->rgdispidNamedArgs[0] == DISPID_THIS, "pdp->rgdispidNamedArgs[0] = %ld\n", pdp->rgdispidNamedArgs[0]); + ok(V_VT(&pdp->rgvarg[0]) == VT_DISPATCH, "V_VT(rgvarg[0]) = %d\n", V_VT(&pdp->rgvarg[0])); + ok(V_DISPATCH(&pdp->rgvarg[0]) != NULL, "V_DISPATCH(rgvarg[0]) = NULL\n"); + ok(V_VT(&pdp->rgvarg[1]) == VT_DISPATCH, "V_VT(rgvarg[1]) = %d\n", V_VT(&pdp->rgvarg[1])); + ok(V_DISPATCH(&pdp->rgvarg[1]) != NULL, "V_DISPATCH(rgvarg[1]) = NULL\n"); + ok(V_VT(&pdp->rgvarg[2]) == VT_I4, "V_VT(rgvarg[2]) = %d\n", V_VT(&pdp->rgvarg[2])); + ok(V_I4(&pdp->rgvarg[2]) == 0, "V_I4(rgvarg[2]) = %ld\n", V_I4(&pdp->rgvarg[2])); + ok(V_VT(&pdp->rgvarg[3]) == VT_I4, "V_VT(rgvarg[3]) = %d\n", V_VT(&pdp->rgvarg[3])); + ok(V_I4(&pdp->rgvarg[3]) == 137, "V_I4(rgvarg[3]) = %ld\n", V_I4(&pdp->rgvarg[3])); + }else { + ok(pdp->cArgs == 3, "pdp->cArgs = %d\n", pdp->cArgs); + ok(V_VT(&pdp->rgvarg[0]) == VT_DISPATCH, "V_VT(rgvarg[1]) = %d\n", V_VT(&pdp->rgvarg[1])); + ok(V_DISPATCH(&pdp->rgvarg[0]) != NULL, "V_DISPATCH(rgvarg[1]) = NULL\n"); + ok(V_VT(&pdp->rgvarg[1]) == VT_I4, "V_VT(rgvarg[2]) = %d\n", V_VT(&pdp->rgvarg[2])); + ok(V_I4(&pdp->rgvarg[1]) == 0, "V_I4(rgvarg[2]) = %ld\n", V_I4(&pdp->rgvarg[2])); + ok(V_VT(&pdp->rgvarg[2]) == VT_I4, "V_VT(rgvarg[3]) = %d\n", V_VT(&pdp->rgvarg[3])); + ok(V_I4(&pdp->rgvarg[2]) == 137, "V_I4(rgvarg[3]) = %ld\n", V_I4(&pdp->rgvarg[3])); + ok(pvarRes != NULL, "pvarRes == NULL\n"); + ok(pei != NULL, "pei == NULL\n"); + ok(pspCaller != NULL, "pspCaller == NULL\n"); + } + + V_VT(pvarRes) = VT_EMPTY; + return S_OK; +} + +static IDispatchExVtbl testHostContextDispVtbl = { + DispatchEx_QueryInterface, + DispatchEx_AddRef, + DispatchEx_Release, + DispatchEx_GetTypeInfoCount, + DispatchEx_GetTypeInfo, + DispatchEx_GetIDsOfNames, + DispatchEx_Invoke, + DispatchEx_GetDispID, + testHostContextDisp_InvokeEx, + DispatchEx_DeleteMemberByName, + DispatchEx_DeleteMemberByDispID, + DispatchEx_GetMemberProperties, + DispatchEx_GetMemberName, + DispatchEx_GetNextDispID, + DispatchEx_GetNameSpaceParent +}; + +static IDispatchEx testHostContextDisp = { &testHostContextDispVtbl }; + static HRESULT WINAPI externalDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) { if(!lstrcmpW(bstrName, L"ok")) { @@ -795,6 +852,10 @@ static HRESULT WINAPI externalDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, *pid = DISPID_EXTERNAL_TEST_VARS; return S_OK; } + if(!lstrcmpW(bstrName, L"testHostContext")) { + *pid = DISPID_EXTERNAL_TESTHOSTCTX; + return S_OK; + } if(!lstrcmpW(bstrName, L"getExpectedMimeType")) { *pid = DISPID_EXTERNAL_GETMIMETYPE; return S_OK; @@ -1032,6 +1093,26 @@ static HRESULT WINAPI externalDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID test_script_vars(pdp->cArgs, pdp->rgvarg); return S_OK;
+ case DISPID_EXTERNAL_TESTHOSTCTX: + ok(pdp != NULL, "pdp == NULL\n"); + ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); + ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); + ok(pvarRes != NULL, "pvarRes == NULL\n"); + ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes)); + ok(pei != NULL, "pei == NULL\n"); + if(wFlags == DISPATCH_PROPERTYGET) { + ok(!pdp->rgvarg, "rgvarg != NULL\n"); + ok(!pdp->cArgs, "cArgs = %d\n", pdp->cArgs); + }else { + ok(pdp->rgvarg != NULL, "rgvarg == NULL\n"); + ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs); + ok(V_VT(pdp->rgvarg) == VT_BOOL, "V_VT(rgvarg) = %d\n", V_VT(pdp->rgvarg)); + testHostContextDisp_expect = !!V_BOOL(pdp->rgvarg); + } + V_VT(pvarRes) = VT_DISPATCH; + V_DISPATCH(pvarRes) = (IDispatch*)&testHostContextDisp; + return S_OK; + case DISPID_EXTERNAL_GETMIMETYPE: ok(pdp != NULL, "pdp == NULL\n"); ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/oleobj.c | 2 +- dlls/mshtml/tests/dom.c | 51 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/dlls/mshtml/oleobj.c b/dlls/mshtml/oleobj.c index e6f5239538c..d1853435606 100644 --- a/dlls/mshtml/oleobj.c +++ b/dlls/mshtml/oleobj.c @@ -3380,7 +3380,7 @@ static HRESULT WINAPI HTMLDocumentObj_QueryInterface(IUnknown *iface, REFIID rii }else if(IsEqualGUID(&IID_IEventTarget, riid)) { /* IEventTarget is conditionally exposed. This breaks COM rules when it changes its compat mode, but it is how native works (see tests). */ - if(!This->doc_node || dispex_compat_mode(&This->doc_node->node.event_target.dispex) < COMPAT_MODE_IE9) { + if(!This->doc_node || This->doc_node->document_mode < COMPAT_MODE_IE9) { *ppv = NULL; return E_NOINTERFACE; } diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 4e6ad469b28..6a960bfa21f 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -11731,6 +11731,56 @@ static void test_quirks_mode(void) "</html>", test_document_mode); }
+static void test_document_mode_lock(void) +{ + IEventTarget *event_target; + IPersistStreamInit *init; + IHTMLDocument2 *doc; + IStream *stream; + HRESULT hres; + HGLOBAL mem; + SIZE_T len; + MSG msg; + + notif_doc = doc = create_document(); + if(!doc) + return; + doc_complete = FALSE; + + hres = IHTMLDocument2_QueryInterface(doc, &IID_IEventTarget, (void**)&event_target); + ok(hres == E_NOINTERFACE, "QueryInterface(IID_IEventTarget) returned %08lx.\n", hres); + ok(event_target == NULL, "event_target != NULL\n"); + + len = strlen(doc_blank_ie9); + mem = GlobalAlloc(0, len); + memcpy(mem, doc_blank_ie9, len); + hres = CreateStreamOnHGlobal(mem, TRUE, &stream); + ok(hres == S_OK, "Failed to create stream: %08lx.\n", hres); + + hres = IHTMLDocument2_QueryInterface(doc, &IID_IPersistStreamInit, (void**)&init); + ok(hres == S_OK, "QueryInterface(IID_IPersistStreamInit) failed: %08lx.\n", hres); + + IPersistStreamInit_Load(init, stream); + IPersistStreamInit_Release(init); + IStream_Release(stream); + + set_client_site(doc, TRUE); + do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink); + + while(!doc_complete && GetMessageW(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + + hres = IHTMLDocument2_QueryInterface(doc, &IID_IEventTarget, (void**)&event_target); + ok(hres == S_OK, "QueryInterface(IID_IEventTarget) returned %08lx.\n", hres); + ok(event_target != NULL, "event_target == NULL\n"); + IEventTarget_Release(event_target); + + set_client_site(doc, FALSE); + IHTMLDocument2_Release(doc); +} + static void test_custom_user_agent(IHTMLDocument2 *doc) { static const WCHAR ua[] = L"1234567890xxxABC"; @@ -11830,6 +11880,7 @@ START_TEST(dom) run_domtest(doctype_str, test_doctype);
test_quirks_mode(); + test_document_mode_lock();
/* Run this last since it messes with the process-wide user agent */ if (winetest_interactive || ! is_ie_hardened()) {
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52910 Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/tests/htmldoc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/mshtml/tests/htmldoc.c b/dlls/mshtml/tests/htmldoc.c index bbfac5aa8fa..5b45ccb0c75 100644 --- a/dlls/mshtml/tests/htmldoc.c +++ b/dlls/mshtml/tests/htmldoc.c @@ -808,8 +808,8 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, if(is_mhtml) ok(!bindinfo.dwOptions, "bindinfo.dwOptions=%lx\n", bindinfo.dwOptions); else - ok(bindinfo.dwOptions == 0x80000 || bindinfo.dwOptions == 0x4080000, /* win2k3 */ - "bindinfo.dwOptions=%lx\n", bindinfo.dwOptions); + ok(bindinfo.dwOptions == 0x80000 || bindinfo.dwOptions == 0x4080000 /* win2k3 */ || + bindinfo.dwOptions == 0x20000, "bindinfo.dwOptions=%lx\n", bindinfo.dwOptions); ok(bindinfo.dwOptionsFlags == 0, "bindinfo.dwOptionsFlags=%ld\n", bindinfo.dwOptionsFlags); /* TODO: test dwCodePage */ /* TODO: test securityAttributes */ @@ -1691,8 +1691,8 @@ static HRESULT WINAPI Moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMon ok(bindinfo.dwBindVerb == 0, "bindinfo.dwBindVerb=%ld\n", bindinfo.dwBindVerb); ok(bindinfo.szCustomVerb == 0, "bindinfo.szCustomVerb=%p\n", bindinfo.szCustomVerb); ok(bindinfo.cbstgmedData == 0, "bindinfo.cbstgmedData=%ld\n", bindinfo.cbstgmedData); - ok(bindinfo.dwOptions == 0x80000 || bindinfo.dwOptions == 0x4080000, - "bindinfo.dwOptions=%lx\n", bindinfo.dwOptions); + ok(bindinfo.dwOptions == 0x80000 || bindinfo.dwOptions == 0x4080000 || + bindinfo.dwOptions == 0x20000, "bindinfo.dwOptions=%lx\n", bindinfo.dwOptions); ok(bindinfo.dwOptionsFlags == 0, "bindinfo.dwOptionsFlags=%ld\n", bindinfo.dwOptionsFlags); /* TODO: test dwCodePage */ /* TODO: test securityAttributes */
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53530 Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/tests/htmldoc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/tests/htmldoc.c b/dlls/mshtml/tests/htmldoc.c index 5b45ccb0c75..e4780e9c379 100644 --- a/dlls/mshtml/tests/htmldoc.c +++ b/dlls/mshtml/tests/htmldoc.c @@ -6018,10 +6018,12 @@ static void test_download(DWORD flags) SET_EXPECT(CountEntries); SET_EXPECT(Exec_HTTPEQUIV_DONE); } - if(nav_url || support_wbapp) { + if(nav_url || support_wbapp || editmode) { SET_EXPECT(UpdateUI); SET_EXPECT(Exec_UPDATECOMMANDS); SET_EXPECT(Exec_SETTITLE); + } + if(nav_url || support_wbapp) { if(flags & DWL_EXPECT_HISTUPDATE) SET_EXPECT(Exec_Explorer_38); SET_EXPECT(UpdateBackForwardState); @@ -6126,10 +6128,12 @@ static void test_download(DWORD flags) CHECK_CALLED(Exec_HTTPEQUIV_DONE); } SET_CALLED(SetStatusText); - if(nav_url || support_wbapp) { /* avoiding race, FIXME: find better way */ + if(nav_url || support_wbapp || editmode) { /* avoiding race, FIXME: find better way */ CLEAR_CALLED(UpdateUI); CLEAR_CALLED(Exec_UPDATECOMMANDS); CLEAR_CALLED(Exec_SETTITLE); + } + if(nav_url || support_wbapp) { if(flags & DWL_EXPECT_HISTUPDATE) { if(flags & DWL_FROM_HISTORY) CHECK_CALLED_BROKEN(Exec_Explorer_38); /* Some old IEs don't call it. */
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- include/mshtmhst.idl | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/include/mshtmhst.idl b/include/mshtmhst.idl index 81b16ed5d62..6cc500ed7a9 100644 --- a/include/mshtmhst.idl +++ b/include/mshtmhst.idl @@ -44,11 +44,25 @@ cpp_quote("#define HTMLDLG_MODAL 0x0020") cpp_quote("#define HTMLDLG_MODELESS 0x0040") cpp_quote("#define HTMLDLG_PRINT_TEMPLATE 0x0080") cpp_quote("#define HTMLDLG_VERIFY 0x0100") +cpp_quote("#define HTMLDLG_ALLOW_UNKNOWN_THREAD 0x0200")
cpp_quote("#define PRINT_DONTBOTHERUSER 0x0001") cpp_quote("#define PRINT_WAITFORCOMPLETION 0x0002")
+cpp_quote("#define CMDID_SCRIPTSITE_URL 0") +cpp_quote("#define CMDID_SCRIPTSITE_HTMLDLGTRUST 1") +cpp_quote("#define CMDID_SCRIPTSITE_SECSTATE 2") +cpp_quote("#define CMDID_SCRIPTSITE_SID 3") +cpp_quote("#define CMDID_SCRIPTSITE_TRUSTEDDOC 4") +cpp_quote("#define CMDID_SCRIPTSITE_SECURITY_WINDOW 5") +cpp_quote("#define CMDID_SCRIPTSITE_NAMESPACE 6") +cpp_quote("#define CMDID_SCRIPTSITE_IURI 7") +cpp_quote("#define CMDID_HOSTCONTEXT_URL 8") +cpp_quote("#define CMDID_SCRIPTSITE_ALLOWRECOVERY 9") +cpp_quote("#define CMDID_SCRIPTSITE_BASEIURI 10") + cpp_quote("DEFINE_GUID(CGID_MSHTML, 0xde4ba900,0x59ca,0x11cf,0x95,0x92,0x44,0x45,0x53,0x54,0x00,0x00);") +cpp_quote("DEFINE_GUID(CGID_ScriptSite, 0x3050f3f1,0x98b5,0x11cf,0xbb,0x82,0x00,0xaa,0x00,0xbd,0xce,0x0b);") cpp_quote("#define CMDSETID_Forms3 CGID_MSHTML")
cpp_quote("#if defined(__GNUC__)")
Jacek Caban (@jacek) commented about dlls/mshtml/tests/script.c:
static IDispatchEx scriptDisp = { &scriptDispVtbl };
+static BOOL testHostContextDisp_expect;
I think it would be better to have two separated test functions: one expecting 'this' argument and one not expecting it and get rid of this global value.
Jacek Caban (@jacek) commented about dlls/mshtml/nsevents.c:
IHTMLDOMNode_AddRef(&doc->node.IHTMLDOMNode_iface);
- /* Keep a ref to the window as well, some apps navigate during the notifications */
- IHTMLWindow2_AddRef(&doc->window->base.IHTMLWindow2_iface);
The problem is not unique to this event handler. Note that if we'd keep a reference to window instead of document, it would be probably enough. Since those event listeners already operate on the window, maybe it would be better to just store window, instead of document, in nsDocumentEventListener.
On Tue Nov 29 19:30:03 2022 +0000, Jacek Caban wrote:
The problem is not unique to this event handler. Note that if we'd keep a reference to window instead of document, it would be probably enough. Since those event listeners already operate on the window, maybe it would be better to just store window, instead of document, in nsDocumentEventListener.
Unfortunately I don't think that would be correct, some documents have no window, and that's totally normal (for example those created with createHTMLDocument). Wouldn't events still need to work on them?
How about using a single generic handler (HandleEvent) that obtains refs to the window, calls the specific specialized handler indirectly, and then releases the window? So it's done for all handlers from only one place.
On Tue Nov 29 19:55:52 2022 +0000, Gabriel Ivăncescu wrote:
Unfortunately I don't think that would be correct, some documents have no window, and that's totally normal (for example those created with createHTMLDocument). Wouldn't events still need to work on them? How about using a single generic handler (HandleEvent) that obtains refs to the window, calls the specific specialized handler indirectly, and then releases the window? So it's done for all handlers from only one place.
Yes, that may work.