mshtml: Introduce query_interface in dispex vtbl and use it for DOM Nodes.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
This commit is contained in:
Gabriel Ivăncescu 2023-09-07 16:07:00 +03:00 committed by Alexandre Julliard
parent c7f18c3118
commit 47393c300e
7 changed files with 53 additions and 32 deletions

View file

@ -1968,9 +1968,15 @@ static IDispatchExVtbl DispatchExVtbl = {
BOOL dispex_query_interface(DispatchEx *This, REFIID riid, void **ppv)
{
if(IsEqualGUID(&IID_IDispatch, riid))
*ppv = &This->IDispatchEx_iface;
else if(IsEqualGUID(&IID_IDispatchEx, riid))
TRACE("%s (%p)->(%s %p)\n", This->info->desc->name, This, debugstr_mshtml_guid(riid), ppv);
if(This->info->desc->vtbl->query_interface) {
*ppv = This->info->desc->vtbl->query_interface(This, riid);
if(*ppv)
goto ret;
}
if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IDispatch, riid) || IsEqualGUID(&IID_IDispatchEx, riid))
*ppv = &This->IDispatchEx_iface;
else if(IsEqualGUID(&IID_nsXPCOMCycleCollectionParticipant, riid)) {
*ppv = &dispex_ccp;
@ -1978,19 +1984,18 @@ BOOL dispex_query_interface(DispatchEx *This, REFIID riid, void **ppv)
}else if(IsEqualGUID(&IID_nsCycleCollectionISupports, riid)) {
*ppv = &This->IDispatchEx_iface;
return TRUE;
}else if(IsEqualGUID(&IID_IDispatchJS, riid))
}else if(IsEqualGUID(&IID_IDispatchJS, riid) ||
IsEqualGUID(&IID_UndocumentedScriptIface, riid) ||
IsEqualGUID(&IID_IMarshal, riid) ||
IsEqualGUID(&IID_IManagedObject, riid)) {
*ppv = NULL;
else if(IsEqualGUID(&IID_UndocumentedScriptIface, riid))
*ppv = NULL;
else if(IsEqualGUID(&IID_IMarshal, riid))
*ppv = NULL;
else if(IsEqualGUID(&IID_IManagedObject, riid))
*ppv = NULL;
else
return TRUE;
}else {
return FALSE;
}
if(*ppv)
IUnknown_AddRef((IUnknown*)*ppv);
ret:
IDispatchEx_AddRef(&This->IDispatchEx_iface);
return TRUE;
}

View file

@ -355,6 +355,7 @@ static IHTMLEventObj *DocumentType_set_current_event(DispatchEx *dispex, IHTMLEv
static const event_target_vtbl_t DocumentType_event_target_vtbl = {
{
.query_interface = HTMLDOMNode_query_interface,
.destructor = HTMLDOMNode_destructor,
.traverse = HTMLDOMNode_traverse,
.unlink = HTMLDOMNode_unlink
@ -6067,6 +6068,7 @@ static HRESULT HTMLDocumentNode_location_hook(DispatchEx *dispex, WORD flags, DI
static const event_target_vtbl_t HTMLDocumentNode_event_target_vtbl = {
{
.query_interface = HTMLDOMNode_query_interface,
.destructor = HTMLDOMNode_destructor,
.traverse = HTMLDOMNode_traverse,
.unlink = HTMLDOMNode_unlink,

View file

@ -7350,6 +7350,7 @@ static const tid_t HTMLElement_iface_tids[] = {
const event_target_vtbl_t HTMLElement_event_target_vtbl = {
{
.query_interface = HTMLDOMNode_query_interface,
.destructor = HTMLDOMNode_destructor,
.traverse = HTMLDOMNode_traverse,
.unlink = HTMLDOMNode_unlink,

View file

@ -4564,6 +4564,19 @@ static HRESULT get_gecko_target(IEventTarget *target, nsIDOMEventTarget **ret)
return S_OK;
}
void *EventTarget_query_interface(EventTarget *event_target, REFIID riid)
{
if(IsEqualGUID(riid, &IID_IEventTarget)) {
if(use_event_quirks(event_target)) {
WARN("IEventTarget queried, but not supported by in document mode\n");
return NULL;
}
return &event_target->IEventTarget_iface;
}
return NULL;
}
HRESULT EventTarget_QI(EventTarget *event_target, REFIID riid, void **ppv)
{
if(IsEqualGUID(riid, &IID_IEventTarget)) {

View file

@ -493,17 +493,11 @@ static HRESULT WINAPI HTMLDOMNode_QueryInterface(IHTMLDOMNode *iface,
{
HTMLDOMNode *This = impl_from_IHTMLDOMNode(iface);
/* FIXME: Get rid of this when dispex handles QI */
if(IsEqualGUID(&IID_nsXPCOMCycleCollectionParticipant, riid) || IsEqualGUID(&IID_nsCycleCollectionISupports, riid)) {
dispex_query_interface(&This->event_target.dispex, riid, ppv);
return S_OK;
}
if((*ppv = This->vtbl->qi(This, riid))) {
IHTMLDOMNode_AddRef(&This->IHTMLDOMNode_iface);
return S_OK;
}
if(dispex_query_interface(&This->event_target.dispex, riid, ppv))
return *ppv ? S_OK : E_NOINTERFACE;
*ppv = NULL;
WARN("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
return E_NOINTERFACE;
}
@ -1437,6 +1431,13 @@ static inline HTMLDOMNode *HTMLDOMNode_from_DispatchEx(DispatchEx *iface)
return CONTAINING_RECORD(iface, HTMLDOMNode, event_target.dispex);
}
void *HTMLDOMNode_query_interface(DispatchEx *dispex, REFIID riid)
{
HTMLDOMNode *This = HTMLDOMNode_from_DispatchEx(dispex);
return This->vtbl->qi(This, riid);
}
void HTMLDOMNode_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb)
{
HTMLDOMNode *This = HTMLDOMNode_from_DispatchEx(dispex);
@ -1477,9 +1478,6 @@ void HTMLDOMNode_destructor(DispatchEx *dispex)
void *HTMLDOMNode_QI(HTMLDOMNode *This, REFIID riid)
{
IUnknown *unk;
HRESULT hres;
if(IsEqualGUID(&IID_IUnknown, riid))
return &This->IHTMLDOMNode_iface;
if(IsEqualGUID(&IID_IDispatch, riid))
@ -1491,12 +1489,7 @@ void *HTMLDOMNode_QI(HTMLDOMNode *This, REFIID riid)
if(IsEqualGUID(&IID_IHTMLDOMNode3, riid))
return &This->IHTMLDOMNode3_iface;
hres = EventTarget_QI(&This->event_target, riid, (void**)&unk);
if(hres != S_OK)
return NULL;
IUnknown_Release(unk);
return unk;
return EventTarget_query_interface(&This->event_target, riid);
}
static HRESULT HTMLDOMNode_clone(HTMLDOMNode *This, nsIDOMNode *nsnode, HTMLDOMNode **ret)
@ -1542,6 +1535,7 @@ void HTMLDOMNode_Init(HTMLDocumentNode *doc, HTMLDOMNode *node, nsIDOMNode *nsno
}
static const dispex_static_data_vtbl_t HTMLDOMNode_dispex_vtbl = {
.query_interface = HTMLDOMNode_query_interface,
.destructor = HTMLDOMNode_destructor,
.traverse = HTMLDOMNode_traverse,
.unlink = HTMLDOMNode_unlink

View file

@ -352,6 +352,7 @@ static const NodeImplVtbl HTMLDOMTextNodeImplVtbl = {
};
static const dispex_static_data_vtbl_t HTMLDOMTextNode_dispex_vtbl = {
.query_interface = HTMLDOMNode_query_interface,
.destructor = HTMLDOMNode_destructor,
.traverse = HTMLDOMNode_traverse,
.unlink = HTMLDOMNode_unlink

View file

@ -352,6 +352,9 @@ typedef struct {
- dynamic props: These props are generally allocated by external code (e.g. 'document.wine = 42' creates 'wine' dynamic prop on document)
*/
typedef struct {
/* Used to provide object specific interfaces (do not AddRef, just return the iface) */
void *(*query_interface)(DispatchEx*,REFIID);
/* Used to implement Cycle Collection callbacks; note that the destructor is not optional!
Unlike delete_cycle_collectable, unlink is called before the destructor (if available). */
void (*destructor)(DispatchEx*);
@ -1207,10 +1210,12 @@ void HTMLDOMNode_Init(HTMLDocumentNode*,HTMLDOMNode*,nsIDOMNode*,dispex_static_d
void HTMLElement_Init(HTMLElement*,HTMLDocumentNode*,nsIDOMElement*,dispex_static_data_t*);
void EventTarget_Init(EventTarget*,IUnknown*,dispex_static_data_t*,compat_mode_t);
void *EventTarget_query_interface(EventTarget*,REFIID);
HRESULT EventTarget_QI(EventTarget*,REFIID,void**);
void EventTarget_init_dispex_info(dispex_data_t*,compat_mode_t);
void *HTMLDOMNode_QI(HTMLDOMNode*,REFIID);
void *HTMLDOMNode_query_interface(DispatchEx*,REFIID);
void HTMLDOMNode_destructor(DispatchEx*);
void HTMLDOMNode_traverse(DispatchEx*,nsCycleCollectionTraversalCallback*);
void HTMLDOMNode_unlink(DispatchEx*);