Jacek Caban : mshtml: Added support for 'document' and 'window' script for attribute values.

Alexandre Julliard julliard at winehq.org
Tue Oct 1 14:54:28 CDT 2013


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Oct  1 15:43:52 2013 +0200

mshtml: Added support for 'document' and 'window' script for attribute values.

---

 dlls/mshtml/htmlevent.c       |    6 ++--
 dlls/mshtml/htmlevent.h       |    2 +-
 dlls/mshtml/script.c          |   46 +++++++++++++++++++++++++++-------------
 dlls/mshtml/tests/events.html |    8 ++++++-
 4 files changed, 42 insertions(+), 20 deletions(-)

diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c
index a7b2969..a564907 100644
--- a/dlls/mshtml/htmlevent.c
+++ b/dlls/mshtml/htmlevent.c
@@ -1510,11 +1510,11 @@ HRESULT detach_event(event_target_t *event_target, HTMLDocument *doc, BSTR name,
     return S_OK;
 }
 
-void bind_elem_event(HTMLDocumentNode *doc, HTMLElement *elem, const WCHAR *event, IDispatch *disp)
+void bind_node_event(HTMLDocumentNode *doc, event_target_t **event_target, HTMLDOMNode *node, const WCHAR *event, IDispatch *disp)
 {
     eventid_t eid;
 
-    TRACE("(%p %p %s %p)\n", doc, elem, debugstr_w(event), disp);
+    TRACE("(%p %p %p %s %p)\n", doc, event_target, node, debugstr_w(event), disp);
 
     eid = attr_to_eid(event);
     if(eid == EVENTID_LAST) {
@@ -1522,7 +1522,7 @@ void bind_elem_event(HTMLDocumentNode *doc, HTMLElement *elem, const WCHAR *even
         return;
     }
 
-    set_event_handler_disp(&elem->node.event_target, elem->node.nsnode, doc, eid, disp);
+    set_event_handler_disp(event_target, node ? node->nsnode : NULL, doc, eid, disp);
 }
 
 void update_cp_events(HTMLInnerWindow *window, event_target_t **event_target_ptr, cp_static_data_t *cp, nsIDOMNode *nsnode)
diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h
index ca39038..abd19c2 100644
--- a/dlls/mshtml/htmlevent.h
+++ b/dlls/mshtml/htmlevent.h
@@ -62,7 +62,7 @@ void update_cp_events(HTMLInnerWindow*,event_target_t**,cp_static_data_t*,nsIDOM
 HRESULT doc_init_events(HTMLDocumentNode*) DECLSPEC_HIDDEN;
 void detach_events(HTMLDocumentNode *doc) DECLSPEC_HIDDEN;
 HRESULT create_event_obj(IHTMLEventObj**) DECLSPEC_HIDDEN;
-void bind_elem_event(HTMLDocumentNode*,HTMLElement*,const WCHAR*,IDispatch*) DECLSPEC_HIDDEN;
+void bind_node_event(HTMLDocumentNode*,event_target_t**,HTMLDOMNode*,const WCHAR*,IDispatch*) DECLSPEC_HIDDEN;
 
 void init_nsevents(HTMLDocumentNode*) DECLSPEC_HIDDEN;
 void release_nsevents(HTMLDocumentNode*) DECLSPEC_HIDDEN;
diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c
index 3174bd2..8a74554 100644
--- a/dlls/mshtml/script.c
+++ b/dlls/mshtml/script.c
@@ -1046,11 +1046,12 @@ IDispatch *get_script_disp(ScriptHost *script_host)
     return disp;
 }
 
-static HTMLElement *find_event_target(HTMLDocumentNode *doc, HTMLScriptElement *script_elem)
+static event_target_t **find_event_target(HTMLDocumentNode *doc, HTMLScriptElement *script_elem, HTMLDOMNode **ret_target_node)
 {
+    HTMLDOMNode *target_node = NULL;
+    event_target_t **target = NULL;
     const PRUnichar *target_id;
     nsAString target_id_str;
-    HTMLElement *elem;
     nsresult nsres;
     HRESULT hres;
 
@@ -1063,17 +1064,27 @@ static HTMLElement *find_event_target(HTMLDocumentNode *doc, HTMLScriptElement *
     }
 
     nsAString_GetData(&target_id_str, &target_id);
-    if(!*target_id || !strcmpW(target_id, documentW) || !strcmpW(target_id, windowW)) {
-        FIXME("for %s not supported\n", debugstr_w(target_id));
-        elem = NULL;
+    if(!*target_id) {
+        FIXME("Empty for attribute\n");
+    }else if(!strcmpW(target_id, documentW)) {
+        target = &doc->node.event_target;
+        target_node = &doc->node;
+        IHTMLDOMNode_AddRef(&target_node->IHTMLDOMNode_iface);
+    }else if(!strcmpW(target_id, windowW)) {
+        target = &doc->body_event_target;
     }else {
-        hres = get_doc_elem_by_id(doc, target_id, &elem);
-        if(FAILED(hres))
-            elem = NULL;
+        HTMLElement *target_elem;
+
+        hres = get_doc_elem_by_id(doc, target_id, &target_elem);
+        if(SUCCEEDED(hres) && target_elem) {
+            target_node = &target_elem->node;
+            target = &target_elem->node.event_target;
+        }
     }
     nsAString_Finish(&target_id_str);
 
-    return elem;
+    *ret_target_node = target_node;
+    return target;
 }
 
 static BOOL parse_event_str(WCHAR *event, const WCHAR **args)
@@ -1168,8 +1179,9 @@ void bind_event_scripts(HTMLDocumentNode *doc)
     HTMLPluginContainer *plugin_container;
     nsIDOMHTMLScriptElement *nsscript;
     HTMLScriptElement *script_elem;
-    HTMLElement *event_target;
+    event_target_t **event_target;
     nsIDOMNodeList *node_list;
+    HTMLDOMNode *target_node;
     nsIDOMNode *script_node;
     nsAString selector_str;
     IDispatch *event_disp;
@@ -1216,17 +1228,21 @@ void bind_event_scripts(HTMLDocumentNode *doc)
 
         event_disp = parse_event_elem(doc, script_elem, &event);
         if(event_disp) {
-            event_target = find_event_target(doc, script_elem);
+            event_target = find_event_target(doc, script_elem, &target_node);
             if(event_target) {
-                hres = IHTMLElement_QueryInterface(&event_target->IHTMLElement_iface, &IID_HTMLPluginContainer,
-                        (void**)&plugin_container);
+                if(target_node)
+                    hres = IHTMLDOMNode_QueryInterface(&target_node->IHTMLDOMNode_iface, &IID_HTMLPluginContainer,
+                            (void**)&plugin_container);
+                else
+                    hres = E_NOINTERFACE;
 
                 if(SUCCEEDED(hres))
                     bind_activex_event(doc, plugin_container, event, event_disp);
                 else
-                    bind_elem_event(doc, event_target, event, event_disp);
+                    bind_node_event(doc, event_target, target_node, event, event_disp);
 
-                IHTMLElement_Release(&event_target->IHTMLElement_iface);
+                if(target_node)
+                    IHTMLDOMNode_Release(&target_node->IHTMLDOMNode_iface);
             }
 
             heap_free(event);
diff --git a/dlls/mshtml/tests/events.html b/dlls/mshtml/tests/events.html
index 131ba19..bf8a21f 100644
--- a/dlls/mshtml/tests/events.html
+++ b/dlls/mshtml/tests/events.html
@@ -1,7 +1,7 @@
 <html>
 <head>
 <script>
-var testevent_divid2_called = false, cnt=0;
+var testevent_divid2_called = false, testevent_document_called = false, cnt=0;
 
 function ok(b,m) {
     return external.ok(b, m);
@@ -71,8 +71,11 @@ function test_scriptfor() {
     ok("onclick" in div, "testevent not in div");
     ok(typeof(div.onclick) === "function", "typeof(div.onclick) = " + typeof(div.onclick));
     ok(testevent_divid2_called === false, "testevent_divid2_called = " + testevent_divid2_called);
+    ok(typeof(document.onclick) === "function", "typeof(document.onclick) = " + typeof(document.onclick));
+    ok(testevent_document_called === false, "testevent_document_called = " + testevent_document_called);
     div.click();
     ok(testevent_divid2_called === true, "testevent_divid2_called = " + testevent_divid2_called);
+    ok(testevent_document_called === true, "testevent_document_called = " + testevent_document_called);
 
     ok(!("ontest" in div), "testevent in div");
     ok(typeof(div.ontest) === "undefined", "typeof(div.ontest) = " + typeof(div.ontest));
@@ -136,6 +139,9 @@ function runTests(t) {
 <script event="onclick" for="divid2">
     testevent_divid2_called = true;
 </script>
+<script event="onclick" for="document">
+    testevent_document_called = true;
+</script>
 <script event="ontest" for="divid2">
     ok(false, "unexpected ontest");
 </script>




More information about the wine-cvs mailing list