Module: wine Branch: master Commit: 3108a405e3d0e7c88ce6552ae7552ae1c91eb959 URL: https://gitlab.winehq.org/wine/wine/-/commit/3108a405e3d0e7c88ce6552ae7552ae...
Author: Jacek Caban jacek@codeweavers.com Date: Wed May 29 23:45:53 2024 +0200
mshtml: Use DispatchEx vtbl for elements as window property lookups.
---
dlls/mshtml/dispex.c | 5 ++++ dlls/mshtml/htmlwindow.c | 66 +++++++++++++++++++++++--------------------- dlls/mshtml/mshtml_private.h | 3 ++ 3 files changed, 43 insertions(+), 31 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 3c5f00e35b7..8517ccac554 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1691,6 +1691,11 @@ static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DW
hres = get_dynamic_prop(This, bstrName, grfdex & ~fdexNameEnsure, &dprop); if(FAILED(hres)) { + if(This->info->desc->vtbl->find_dispid) { + hres = This->info->desc->vtbl->find_dispid(This, bstrName, grfdex, pid); + if(SUCCEEDED(hres)) + return hres; + } if(grfdex & fdexNameEnsure) hres = alloc_dynamic_prop(This, bstrName, dprop, &dprop); if(FAILED(hres)) diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 59a0f6d023d..be07072600c 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3700,9 +3700,6 @@ static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, { HTMLWindow *This = impl_from_IDispatchEx(iface); HTMLInnerWindow *window = This->inner_window; - HTMLOuterWindow *frame; - global_prop_t *prop; - IHTMLElement *elem; HRESULT hres;
TRACE("(%p)->(%s %lx %p)\n", This, debugstr_w(bstrName), grfdex, pid); @@ -3711,34 +3708,7 @@ static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, if(hres != DISP_E_UNKNOWNNAME) return hres;
- hres = IDispatchEx_GetDispID(&window->base.inner_window->event_target.dispex.IDispatchEx_iface, bstrName, grfdex, pid); - if(hres != DISP_E_UNKNOWNNAME) - return hres; - - hres = get_frame_by_name(This->outer_window, bstrName, FALSE, &frame); - if(SUCCEEDED(hres) && frame) { - prop = alloc_global_prop(window, GLOBAL_FRAMEVAR, bstrName); - if(!prop) - return E_OUTOFMEMORY; - - *pid = prop_to_dispid(window, prop); - return S_OK; - } - - hres = IHTMLDocument3_getElementById(&window->base.inner_window->doc->IHTMLDocument3_iface, - bstrName, &elem); - if(SUCCEEDED(hres) && elem) { - IHTMLElement_Release(elem); - - prop = alloc_global_prop(window, GLOBAL_ELEMENTVAR, bstrName); - if(!prop) - return E_OUTOFMEMORY; - - *pid = prop_to_dispid(window, prop); - return S_OK; - } - - return DISP_E_UNKNOWNNAME; + return IDispatchEx_GetDispID(&window->base.inner_window->event_target.dispex.IDispatchEx_iface, bstrName, grfdex, pid); }
static HRESULT WINAPI WindowDispEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, @@ -4099,6 +4069,39 @@ static HRESULT HTMLWindow_get_name(DispatchEx *dispex, DISPID id, BSTR *name) return (*name = SysAllocString(This->global_props[idx].name)) ? S_OK : E_OUTOFMEMORY; }
+static HRESULT HTMLWindow_find_dispid(DispatchEx *dispex, BSTR name, DWORD grfdex, DISPID *dispid) +{ + HTMLInnerWindow *This = impl_from_DispatchEx(dispex); + HTMLOuterWindow *frame; + global_prop_t *prop; + IHTMLElement *elem; + HRESULT hres; + + hres = get_frame_by_name(This->base.outer_window, name, FALSE, &frame); + if(SUCCEEDED(hres) && frame) { + prop = alloc_global_prop(This, GLOBAL_FRAMEVAR, name); + if(!prop) + return E_OUTOFMEMORY; + + *dispid = prop_to_dispid(This, prop); + return S_OK; + } + + hres = IHTMLDocument3_getElementById(&This->doc->IHTMLDocument3_iface, name, &elem); + if(SUCCEEDED(hres) && elem) { + IHTMLElement_Release(elem); + + prop = alloc_global_prop(This, GLOBAL_ELEMENTVAR, name); + if(!prop) + return E_OUTOFMEMORY; + + *dispid = prop_to_dispid(This, prop); + return S_OK; + } + + return DISP_E_UNKNOWNNAME; +} + static HRESULT HTMLWindow_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { @@ -4398,6 +4401,7 @@ static const event_target_vtbl_t HTMLWindow_event_target_vtbl = { .unlink = HTMLWindow_unlink, .last_release = HTMLWindow_last_release, .get_name = HTMLWindow_get_name, + .find_dispid = HTMLWindow_find_dispid, .invoke = HTMLWindow_invoke, .next_dispid = HTMLWindow_next_dispid, .get_compat_mode = HTMLWindow_get_compat_mode, diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 1d4f005ba11..52d53ca9e00 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -371,6 +371,9 @@ typedef struct { /* Used when the object has custom props, and this returns DISPIDs for them */ HRESULT (*get_dispid)(DispatchEx*,BSTR,DWORD,DISPID*);
+ /* Similar to get_dispid, but called only when a dynamic property can't be found */ + HRESULT (*find_dispid)(DispatchEx*,BSTR,DWORD,DISPID*); + /* These are called when the object implements GetMemberName, InvokeEx, DeleteMemberByDispID and GetNextDispID for custom props */ HRESULT (*get_name)(DispatchEx*,DISPID,BSTR*); HRESULT (*invoke)(DispatchEx*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*);