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