Jacek Caban : mshtml: Fire readystatechange event on document nodes.

Alexandre Julliard julliard at winehq.org
Thu Mar 18 11:19:30 CDT 2010


Module: wine
Branch: master
Commit: 8629433f5fe8f0e097bec0e916efc262690d403d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=8629433f5fe8f0e097bec0e916efc262690d403d

Author: Jacek Caban <jacek at 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);
 




More information about the wine-cvs mailing list