Module: wine Branch: master Commit: 88a06f18b467a31d96ab5b9c816cf3ee3b2bb2f2 URL: https://gitlab.winehq.org/wine/wine/-/commit/88a06f18b467a31d96ab5b9c816cf3e...
Author: Jacek Caban jacek@codeweavers.com Date: Thu May 30 03:03:11 2024 +0200
mshtml: Use DispatchEx for document node InvokeEx implementation.
---
dlls/mshtml/dispex.c | 6 ++++++ dlls/mshtml/htmldoc.c | 41 +++++++++++++++++++++++++---------------- dlls/mshtml/mshtml_private.h | 3 +++ dlls/mshtml/tests/htmldoc.c | 23 +++++++++++++++++++++++ 4 files changed, 57 insertions(+), 16 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 152d2d4cb66..9c0e9a0b9ec 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1725,6 +1725,12 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc if(wFlags == (DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF)) wFlags = DISPATCH_PROPERTYPUT;
+ if(This->info->desc->vtbl->disp_invoke) { + hres = This->info->desc->vtbl->disp_invoke(This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); + if(hres != S_FALSE) + return hres; + } + switch(get_dispid_type(id)) { case DISPEXPROP_CUSTOM: if(!This->info->desc->vtbl->invoke) diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 41fdffd55e7..8575ff69dcf 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -5066,22 +5066,6 @@ static HRESULT WINAPI DocDispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID { HTMLDocumentNode *This = impl_from_IDispatchEx(iface);
- if(This->window) { - switch(id) { - case DISPID_READYSTATE: - TRACE("DISPID_READYSTATE\n"); - - if(!(wFlags & DISPATCH_PROPERTYGET)) - return E_INVALIDARG; - - V_VT(pvarRes) = VT_I4; - V_I4(pvarRes) = This->window->base.outer_window->readystate; - return S_OK; - default: - break; - } - } - return IDispatchEx_InvokeEx(&This->node.event_target.dispex.IDispatchEx_iface, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); }
@@ -5939,6 +5923,30 @@ static HRESULT HTMLDocumentNode_invoke(DispatchEx *dispex, DISPID id, LCID lcid, return S_OK; }
+static HRESULT HTMLDocumentNode_disp_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params, + VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) +{ + HTMLDocumentNode *This = impl_from_DispatchEx(dispex); + + if(This->window) { + switch(id) { + case DISPID_READYSTATE: + TRACE("DISPID_READYSTATE\n"); + + if(!(flags & DISPATCH_PROPERTYGET)) + return E_INVALIDARG; + + V_VT(res) = VT_I4; + V_I4(res) = This->window->base.outer_window->readystate; + return S_OK; + default: + break; + } + } + + return S_FALSE; +} + static HRESULT HTMLDocumentNode_next_dispid(DispatchEx *dispex, DISPID id, DISPID *pid) { DWORD idx = (id == DISPID_STARTENUM) ? 0 : id - MSHTML_DISPID_CUSTOM_MIN + 1; @@ -6111,6 +6119,7 @@ static const event_target_vtbl_t HTMLDocumentNode_event_target_vtbl = { .get_dispid = HTMLDocumentNode_get_dispid, .find_dispid = HTMLDocumentNode_find_dispid, .invoke = HTMLDocumentNode_invoke, + .disp_invoke = HTMLDocumentNode_disp_invoke, .next_dispid = HTMLDocumentNode_next_dispid, .get_compat_mode = HTMLDocumentNode_get_compat_mode, }, diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 4653da1fdbb..e8e308a81f4 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -383,6 +383,9 @@ typedef struct { HRESULT (*delete)(DispatchEx*,DISPID); HRESULT (*next_dispid)(DispatchEx*,DISPID,DISPID*);
+ /* Similar to invoke, but allows overriding all dispids */ + HRESULT (*disp_invoke)(DispatchEx*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*); + /* Used by objects that want to delay their compat mode initialization until actually needed */ compat_mode_t (*get_compat_mode)(DispatchEx*);
diff --git a/dlls/mshtml/tests/htmldoc.c b/dlls/mshtml/tests/htmldoc.c index f41d5749b3b..ad2544f189a 100644 --- a/dlls/mshtml/tests/htmldoc.c +++ b/dlls/mshtml/tests/htmldoc.c @@ -5681,6 +5681,29 @@ static void _test_readyState(unsigned line, IUnknown *unk) ok_(__FILE__,line) (V_VT(&out) == VT_I4, "V_VT(out)=%d\n", V_VT(&out)); ok_(__FILE__,line) (V_I4(&out) == load_state%5, "VT_I4(out)=%ld, expected %d\n", V_I4(&out), load_state%5);
+ /* check on document node too */ + if(load_state == LD_COMPLETE) { + IHTMLDocument2 *doc_node; + IHTMLWindow2 *window; + + hres = IHTMLDocument2_get_parentWindow(htmldoc, &window); + ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres); + + hres = IHTMLWindow2_get_document(window, &doc_node); + ok(hres == S_OK, "get_document failed: %08lx\n", hres); + + VariantInit(&out); + hres = IHTMLDocument2_Invoke(doc_node, DISPID_READYSTATE, &IID_NULL, 0, DISPATCH_PROPERTYGET, + &dispparams, &out, NULL, NULL); + ok(hres == S_OK, "Invoke(DISPID_READYSTATE) failed: %08lx\n", hres); + + ok_(__FILE__,line) (V_VT(&out) == VT_I4, "V_VT(out)=%d\n", V_VT(&out)); + ok_(__FILE__,line) (V_I4(&out) == load_state%5, "VT_I4(out)=%ld, expected %d\n", V_I4(&out), load_state%5); + + IHTMLDocument2_Release(doc_node); + IHTMLWindow2_Release(window); + } + test_doscroll((IUnknown*)htmldoc);
IHTMLDocument2_Release(htmldoc);