From 12f312daccf5201e4b26d2d76ab4a87411821c15 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Mon, 21 Apr 2008 00:48:18 +0200 Subject: [PATCH] mshtml: Added load event support. --- dlls/mshtml/dispex.c | 29 ++++ dlls/mshtml/htmlevent.c | 339 ++++++++++++++++++++++++++++++++++++++++++- dlls/mshtml/htmlwindow.c | 3 +- dlls/mshtml/mshtml_private.h | 9 ++ dlls/mshtml/nsevents.c | 16 ++ 5 files changed, 389 insertions(+), 7 deletions(-) diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 6596f76bc0e..7dc00637764 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -86,6 +86,35 @@ void release_typelib(void) ITypeLib_Release(typelib); } +void call_disp_func(HTMLDocument *doc, IDispatch *disp) +{ + DISPID named_arg = DISPID_THIS; + VARIANTARG arg; + DISPPARAMS params = {&arg, &named_arg, 1, 1}; + EXCEPINFO ei; + IDispatchEx *dispex; + VARIANT res; + HRESULT hres; + + hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); + if(FAILED(hres)) { + FIXME("Could not get IDispatchEx interface: %08x\n", hres); + return; + } + + V_VT(&arg) = VT_DISPATCH; + V_DISPATCH(&arg) = (IDispatch*)HTMLWINDOW2(doc->window); + VariantInit(&res); + memset(&ei, 0, sizeof(ei)); + + hres = IDispatchEx_InvokeEx(dispex, 0, GetUserDefaultLCID(), DISPATCH_METHOD, ¶ms, &res, &ei, NULL); + IDispatchEx_Release(dispex); + + TRACE("%p returned %08x\n", disp, hres); + + VariantClear(&res); +} + #define DISPATCHEX_THIS(iface) DEFINE_THIS(DispatchEx, IDispatchEx, iface) static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv) diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index fcb5c7ca5df..73c0981c2e4 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -31,11 +31,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); -typedef enum { - EVENTID_LOAD, - EVENTID_LAST -} eventid; - struct event_target_t { IDispatch *event_table[EVENTID_LAST]; }; @@ -52,6 +47,340 @@ static const event_info_t event_info[] = { {loadW, onloadW} }; +typedef struct { + const IHTMLEventObjVtbl *lpIHTMLEventObjVtbl; + LONG ref; +} HTMLEventObj; + +#define HTMLEVENTOBJ(x) ((IHTMLEventObj*) &(x)->lpIHTMLEventObjVtbl) + +#define HTMLEVENTOBJ_THIS(iface) DEFINE_THIS(HTMLEventObj, IHTMLEventObj, iface) + +static HRESULT WINAPI HTMLEventObj_QueryInterface(IHTMLEventObj *iface, REFIID riid, void **ppv) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + + *ppv = NULL; + + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); + *ppv = HTMLEVENTOBJ(This); + }else if(IsEqualGUID(&IID_IDispatch, riid)) { + TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv); + *ppv = HTMLEVENTOBJ(This); + }else if(IsEqualGUID(&IID_IHTMLEventObj, riid)) { + TRACE("(%p)->(IID_IHTMLEventObj %p)\n", This, ppv); + *ppv = HTMLEVENTOBJ(This); + } + + if(*ppv) { + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; + } + + WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); + return E_NOINTERFACE; +} + +static ULONG WINAPI HTMLEventObj_AddRef(IHTMLEventObj *iface) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; +} + +static ULONG WINAPI HTMLEventObj_Release(IHTMLEventObj *iface) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) + heap_free(This); + + return ref; +} + +static HRESULT WINAPI HTMLEventObj_GetTypeInfoCount(IHTMLEventObj *iface, UINT *pctinfo) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, pctinfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_GetTypeInfo(IHTMLEventObj *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_GetIDsOfNames(IHTMLEventObj *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, + lcid, rgDispId); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_Invoke(IHTMLEventObj *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_srcElement(IHTMLEventObj *iface, IHTMLElement **p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_altKey(IHTMLEventObj *iface, VARIANT_BOOL *p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_ctrlKey(IHTMLEventObj *iface, VARIANT_BOOL *p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_shiftKey(IHTMLEventObj *iface, VARIANT_BOOL *p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_put_returnValue(IHTMLEventObj *iface, VARIANT v) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_returnValue(IHTMLEventObj *iface, VARIANT *p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_put_cancelBubble(IHTMLEventObj *iface, VARIANT_BOOL v) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%x)\n", This, v); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_cancelBubble(IHTMLEventObj *iface, VARIANT_BOOL *p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_fromElement(IHTMLEventObj *iface, IHTMLElement **p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_toElement(IHTMLEventObj *iface, IHTMLElement **p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_put_keyCode(IHTMLEventObj *iface, long v) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%ld)\n", This, v); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_keyCode(IHTMLEventObj *iface, long *p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_button(IHTMLEventObj *iface, long *p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_type(IHTMLEventObj *iface, BSTR *p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_qualifier(IHTMLEventObj *iface, BSTR *p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_reason(IHTMLEventObj *iface, long *p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_x(IHTMLEventObj *iface, long *p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_y(IHTMLEventObj *iface, long *p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_clientX(IHTMLEventObj *iface, long *p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_clientY(IHTMLEventObj *iface, long *p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_offsetX(IHTMLEventObj *iface, long *p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_offsetY(IHTMLEventObj *iface, long *p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_screenX(IHTMLEventObj *iface, long *p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_screenY(IHTMLEventObj *iface, long *p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLEventObj_get_srcFilter(IHTMLEventObj *iface, IDispatch **p) +{ + HTMLEventObj *This = HTMLEVENTOBJ_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +#undef HTMLEVENTOBJ_THIS + +static const IHTMLEventObjVtbl HTMLEventObjVtbl = { + HTMLEventObj_QueryInterface, + HTMLEventObj_AddRef, + HTMLEventObj_Release, + HTMLEventObj_GetTypeInfoCount, + HTMLEventObj_GetTypeInfo, + HTMLEventObj_GetIDsOfNames, + HTMLEventObj_Invoke, + HTMLEventObj_get_srcElement, + HTMLEventObj_get_altKey, + HTMLEventObj_get_ctrlKey, + HTMLEventObj_get_shiftKey, + HTMLEventObj_put_returnValue, + HTMLEventObj_get_returnValue, + HTMLEventObj_put_cancelBubble, + HTMLEventObj_get_cancelBubble, + HTMLEventObj_get_fromElement, + HTMLEventObj_get_toElement, + HTMLEventObj_put_keyCode, + HTMLEventObj_get_keyCode, + HTMLEventObj_get_button, + HTMLEventObj_get_type, + HTMLEventObj_get_qualifier, + HTMLEventObj_get_reason, + HTMLEventObj_get_x, + HTMLEventObj_get_y, + HTMLEventObj_get_clientX, + HTMLEventObj_get_clientY, + HTMLEventObj_get_offsetX, + HTMLEventObj_get_offsetY, + HTMLEventObj_get_screenX, + HTMLEventObj_get_screenY, + HTMLEventObj_get_srcFilter +}; + +static IHTMLEventObj *create_event(void) +{ + HTMLEventObj *ret; + + ret = heap_alloc(sizeof(*ret)); + ret->lpIHTMLEventObjVtbl = &HTMLEventObjVtbl; + ret->ref = 1; + + return HTMLEVENTOBJ(ret); +} + +void fire_event(HTMLDocument *doc, eventid_t eid, nsIDOMNode *target) +{ + HTMLDOMNode *node; + + node = get_node(doc, target, FALSE); + if(!node) + return; + + if(node->event_target && node->event_target->event_table[eid]) { + doc->window->event = create_event(); + + call_disp_func(doc, node->event_target->event_table[eid]); + + IHTMLEventObj_Release(doc->window->event); + doc->window->event = NULL; + } +} + void check_event_attr(HTMLDocument *doc, nsIDOMElement *nselem) { const PRUnichar *attr_value; diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 7ae121ab659..e96e860c8ec 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -1046,12 +1046,11 @@ void setup_nswindow(HTMLWindow *This) HTMLWindow *HTMLWindow_Create(HTMLDocument *doc) { - HTMLWindow *ret = heap_alloc(sizeof(HTMLWindow)); + HTMLWindow *ret = heap_alloc_zero(sizeof(HTMLWindow)); ret->lpHTMLWindow2Vtbl = &HTMLWindow2Vtbl; ret->lpHTMLWindow3Vtbl = &HTMLWindow3Vtbl; ret->ref = 1; - ret->nswindow = NULL; ret->doc = doc; if(doc->nscontainer) { diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index e9277f7b769..48f3b1bf9f8 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -81,6 +81,8 @@ typedef struct { HTMLDocument *doc; nsIDOMWindow *nswindow; + IHTMLEventObj *event; + struct list entry; } HTMLWindow; @@ -428,8 +430,14 @@ void get_editor_controller(NSContainer*); void init_nsevents(NSContainer*); nsresult get_nsinterface(nsISupports*,REFIID,void**); +typedef enum { + EVENTID_LOAD, + EVENTID_LAST +} eventid_t; + void check_event_attr(HTMLDocument*,nsIDOMElement*); void release_event_target(event_target_t*); +void fire_event(HTMLDocument*,eventid_t,nsIDOMNode*); void set_document_bscallback(HTMLDocument*,nsChannelBSC*); void set_current_mon(HTMLDocument*,IMoniker*); @@ -540,6 +548,7 @@ void remove_doc_tasks(const HTMLDocument*); HRESULT get_typeinfo(tid_t,ITypeInfo**); void release_typelib(void); +void call_disp_func(HTMLDocument*,IDispatch*); DEFINE_GUID(CLSID_AboutProtocol, 0x3050F406, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B); DEFINE_GUID(CLSID_JSProtocol, 0x3050F3B2, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B); diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index 12e299eabe8..5b72a2d9f79 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -129,6 +129,9 @@ static nsresult NSAPI handle_keypress(nsIDOMEventListener *iface, static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event) { NSContainer *This = NSEVENTLIST_THIS(iface)->This; + nsIDOMHTMLDocument *nshtmldoc; + nsIDOMHTMLElement *nsbody = NULL; + nsIDOMDocument *nsdoc; task_t *task; TRACE("(%p)\n", This); @@ -159,6 +162,19 @@ static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event */ push_task(task); + + nsIWebNavigation_GetDocument(This->navigation, &nsdoc); + nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMHTMLDocument, (void**)&nshtmldoc); + nsIDOMDocument_Release(nsdoc); + + nsIDOMHTMLDocument_GetBody(nshtmldoc, &nsbody); + nsIDOMHTMLDocument_Release(nshtmldoc); + + if(nsbody) { + fire_event(This->doc, EVENTID_LOAD, (nsIDOMNode*)nsbody); + nsIDOMHTMLElement_Release(nsbody); + } + return NS_OK; } -- 2.11.4.GIT