Module: wine Branch: master Commit: 8629433f5fe8f0e097bec0e916efc262690d403d URL: http://source.winehq.org/git/wine.git/?a=commit;h=8629433f5fe8f0e097bec0e916...
Author: Jacek Caban jacek@codeweavers.com Date: Thu Mar 18 01:04:45 2010 +0100
mshtml: Fire readystatechange event on document nodes.
---
dlls/mshtml/htmlevent.c | 13 +++++++---- dlls/mshtml/htmlevent.h | 2 +- dlls/mshtml/nsevents.c | 4 +- dlls/mshtml/persist.c | 6 ++++- dlls/mshtml/tests/events.c | 48 +++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 61 insertions(+), 12 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 54429c3..263026d 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -882,7 +882,7 @@ static void call_event_handlers(HTMLDocumentNode *doc, IHTMLEventObj *event_obj, } }
-void fire_event(HTMLDocumentNode *doc, eventid_t eid, nsIDOMNode *target, nsIDOMEvent *nsevent) +void fire_event(HTMLDocumentNode *doc, eventid_t eid, BOOL set_event, nsIDOMNode *target, nsIDOMEvent *nsevent) { IHTMLEventObj *prev_event, *event_obj = NULL; nsIDOMNode *parent, *nsnode; @@ -892,7 +892,9 @@ void fire_event(HTMLDocumentNode *doc, eventid_t eid, nsIDOMNode *target, nsIDOM TRACE("(%p) %s\n", doc, debugstr_w(event_info[eid].name));
prev_event = doc->basedoc.window->event; - event_obj = doc->basedoc.window->event = create_event(get_node(doc, target, TRUE), eid, nsevent); + if(set_event) + event_obj = create_event(get_node(doc, target, TRUE), eid, nsevent); + doc->basedoc.window->event = event_obj;
nsIDOMNode_GetNodeType(target, &node_type); nsnode = target; @@ -949,7 +951,8 @@ void fire_event(HTMLDocumentNode *doc, eventid_t eid, nsIDOMNode *target, nsIDOM if(nsnode) nsIDOMNode_Release(nsnode);
- IHTMLEventObj_Release(event_obj); + if(event_obj) + IHTMLEventObj_Release(event_obj); doc->basedoc.window->event = prev_event; }
@@ -971,7 +974,7 @@ HRESULT dispatch_event(HTMLDOMNode *node, const WCHAR *event_name, VARIANT *even return E_NOTIMPL; }
- fire_event(node->doc, eid, node->nsnode, NULL); + fire_event(node->doc, eid, TRUE, node->nsnode, NULL);
*cancelled = VARIANT_TRUE; /* FIXME */ return S_OK; @@ -989,7 +992,7 @@ HRESULT call_event(HTMLDOMNode *node, eventid_t eid) return hres; }
- fire_event(node->doc, eid, node->nsnode, NULL); + fire_event(node->doc, eid, TRUE, node->nsnode, NULL); return S_OK; }
diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index 96ff4cd..9d0e544 100644 --- a/dlls/mshtml/htmlevent.h +++ b/dlls/mshtml/htmlevent.h @@ -42,7 +42,7 @@ typedef enum { eventid_t str_to_eid(LPCWSTR); void check_event_attr(HTMLDocumentNode*,nsIDOMElement*); void release_event_target(event_target_t*); -void fire_event(HTMLDocumentNode*,eventid_t,nsIDOMNode*,nsIDOMEvent*); +void fire_event(HTMLDocumentNode*,eventid_t,BOOL,nsIDOMNode*,nsIDOMEvent*); HRESULT set_event_handler(event_target_t**,HTMLDocumentNode*,eventid_t,VARIANT*); HRESULT get_event_handler(event_target_t**,eventid_t,VARIANT*); HRESULT attach_event(event_target_t**,HTMLDocument*,BSTR,IDispatch*,VARIANT_BOOL*); diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index 0f5b864..ce622d2 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -254,7 +254,7 @@ static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event
nsIDOMHTMLDocument_GetBody(doc->nsdoc, &nsbody); if(nsbody) { - fire_event(doc, EVENTID_LOAD, (nsIDOMNode*)nsbody, event); + fire_event(doc, EVENTID_LOAD, TRUE, (nsIDOMNode*)nsbody, event); nsIDOMHTMLElement_Release(nsbody); }
@@ -290,7 +290,7 @@ static nsresult NSAPI handle_htmlevent(nsIDOMEventListener *iface, nsIDOMEvent * return NS_OK; }
- fire_event(doc, eid, nsnode, event); + fire_event(doc, eid, TRUE, nsnode, event);
nsIDOMNode_Release(nsnode);
diff --git a/dlls/mshtml/persist.c b/dlls/mshtml/persist.c index 6aca13f..44ccd0f 100644 --- a/dlls/mshtml/persist.c +++ b/dlls/mshtml/persist.c @@ -283,11 +283,15 @@ HRESULT set_moniker(HTMLDocument *This, IMoniker *mon, IBindCtx *pibc, nsChannel void set_ready_state(HTMLWindow *window, READYSTATE readystate) { window->readystate = readystate; + if(window->doc_obj && window->doc_obj->basedoc.window == window) call_property_onchanged(&window->doc_obj->basedoc.cp_propnotif, DISPID_READYSTATE); + + fire_event(window->doc, EVENTID_READYSTATECHANGE, FALSE, window->doc->node.nsnode, NULL); + if(window->frame_element) fire_event(window->frame_element->element.node.doc, EVENTID_READYSTATECHANGE, - window->frame_element->element.node.nsnode, NULL); + TRUE, window->frame_element->element.node.nsnode, NULL); }
static HRESULT get_doc_string(HTMLDocumentNode *This, char **str) diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index d2d1db7..55171be 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -67,6 +67,7 @@ DEFINE_EXPECT(div_onclick_disp); DEFINE_EXPECT(iframe_onreadystatechange_loading); DEFINE_EXPECT(iframe_onreadystatechange_interactive); DEFINE_EXPECT(iframe_onreadystatechange_complete); +DEFINE_EXPECT(iframedoc_onreadystatechange);
static HWND container_hwnd = NULL; static IHTMLWindow2 *window; @@ -879,14 +880,35 @@ static HRESULT WINAPI body_onclick(IDispatchEx *iface, DISPID id, LCID lcid, WOR
EVENT_HANDLER_FUNC_OBJ(body_onclick);
+static HRESULT WINAPI iframedoc_onreadystatechange(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, + VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) +{ + IHTMLEventObj *event = NULL; + HRESULT hres; + + CHECK_EXPECT2(iframedoc_onreadystatechange); + test_event_args(&DIID_DispHTMLDocument, id, wFlags, pdp, pvarRes, pei, pspCaller); + + event = (void*)0xdeadbeef; + hres = IHTMLWindow2_get_event(window, &event); + ok(hres == S_OK, "get_event failed: %08x\n", hres); + ok(!event, "event = %p\n", event); + + return S_OK; +} + +EVENT_HANDLER_FUNC_OBJ(iframedoc_onreadystatechange); + static HRESULT WINAPI iframe_onreadystatechange(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { + IHTMLWindow2 *iframe_window; + IHTMLDocument2 *iframe_doc; IHTMLFrameBase2 *iframe; IHTMLElement2 *elem2; IHTMLElement *elem; VARIANT v; - BSTR str; + BSTR str, str2; HRESULT hres;
test_event_args(&DIID_DispHTMLIFrame, id, wFlags, pdp, pvarRes, pei, pspCaller); @@ -913,15 +935,33 @@ static HRESULT WINAPI iframe_onreadystatechange(IDispatchEx *iface, DISPID id, L ok(!lstrcmpW(str, V_BSTR(&v)), "ready states differ\n"); VariantClear(&v);
- if(!strcmp_wa(str, "loading")) + hres = IHTMLFrameBase2_get_contentWindow(iframe, &iframe_window); + ok(hres == S_OK, "get_contentDocument failed: %08x\n", hres); + + hres = IHTMLWindow2_get_document(iframe_window, &iframe_doc); + IHTMLWindow2_Release(iframe_window); + ok(hres == S_OK, "get_document failed: %08x\n", hres); + + hres = IHTMLDocument2_get_readyState(iframe_doc, &str2); + ok(!lstrcmpW(str, str2), "unexpected document readyState %s\n", wine_dbgstr_w(str2)); + SysFreeString(str2); + + if(!strcmp_wa(str, "loading")) { CHECK_EXPECT(iframe_onreadystatechange_loading); - else if(!strcmp_wa(str, "interactive")) + + V_VT(&v) = VT_DISPATCH; + V_DISPATCH(&v) = (IDispatch*)&iframedoc_onreadystatechange_obj; + hres = IHTMLDocument2_put_onreadystatechange(iframe_doc, v); + ok(hres == S_OK, "put_onreadystatechange: %08x\n", hres); + }else if(!strcmp_wa(str, "interactive")) CHECK_EXPECT(iframe_onreadystatechange_interactive); else if(!strcmp_wa(str, "complete")) CHECK_EXPECT(iframe_onreadystatechange_complete); else ok(0, "unexpected state %s\n", wine_dbgstr_w(str));
+ IHTMLDocument2_Release(iframe_doc); + IHTMLFrameBase2_Release(iframe); return S_OK; }
@@ -1307,10 +1347,12 @@ static void test_onreadystatechange(IHTMLDocument2 *doc) ok(hres == S_OK, "put_src failed: %08x\n", hres);
SET_EXPECT(iframe_onreadystatechange_loading); + SET_EXPECT(iframedoc_onreadystatechange); SET_EXPECT(iframe_onreadystatechange_interactive); SET_EXPECT(iframe_onreadystatechange_complete); pump_msgs(&called_iframe_onreadystatechange_complete); CHECK_CALLED(iframe_onreadystatechange_loading); + CHECK_CALLED(iframedoc_onreadystatechange); CHECK_CALLED(iframe_onreadystatechange_interactive); CHECK_CALLED(iframe_onreadystatechange_complete);