Jacek Caban : mshtml: Delay onreadystateevent notification if script elemenet is not added by parser.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Dec 24 13:40:37 CST 2014


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Dec 24 13:10:21 2014 +0100

mshtml: Delay onreadystateevent notification if script elemenet is not added by parser.

---

 dlls/mshtml/htmlscript.h |  1 +
 dlls/mshtml/script.c     | 50 ++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/dlls/mshtml/htmlscript.h b/dlls/mshtml/htmlscript.h
index 8698be8..ad493c9 100644
--- a/dlls/mshtml/htmlscript.h
+++ b/dlls/mshtml/htmlscript.h
@@ -24,6 +24,7 @@ typedef struct {
     nsIDOMHTMLScriptElement *nsscript;
     BOOL parsed;
     BOOL parse_on_bind;
+    BOOL pending_readystatechange_event;
     READYSTATE readystate;
 } HTMLScriptElement;
 
diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c
index de4fc20..54e84e1 100644
--- a/dlls/mshtml/script.c
+++ b/dlls/mshtml/script.c
@@ -702,12 +702,58 @@ static ScriptHost *create_script_host(HTMLInnerWindow *window, const GUID *guid)
     return ret;
 }
 
+typedef struct {
+    task_t header;
+    HTMLScriptElement *elem;
+} fire_readystatechange_task_t;
+
+static void fire_readystatechange_proc(task_t *_task)
+{
+    fire_readystatechange_task_t *task = (fire_readystatechange_task_t*)_task;
+
+    if(!task->elem->pending_readystatechange_event)
+        return;
+
+    task->elem->pending_readystatechange_event = FALSE;
+    fire_event(task->elem->element.node.doc, EVENTID_READYSTATECHANGE, FALSE, task->elem->element.node.nsnode, NULL, NULL);
+}
+
+static void fire_readystatechange_task_destr(task_t *_task)
+{
+    fire_readystatechange_task_t *task = (fire_readystatechange_task_t*)_task;
+
+    IHTMLScriptElement_Release(&task->elem->IHTMLScriptElement_iface);
+}
+
 static void set_script_elem_readystate(HTMLScriptElement *script_elem, READYSTATE readystate)
 {
     script_elem->readystate = readystate;
 
-    if(readystate != READYSTATE_INTERACTIVE)
-        fire_event(script_elem->element.node.doc, EVENTID_READYSTATECHANGE, FALSE, script_elem->element.node.nsnode, NULL, NULL);
+    if(readystate != READYSTATE_INTERACTIVE) {
+        if(!script_elem->element.node.doc->window->parser_callback_cnt) {
+            fire_readystatechange_task_t *task;
+            HRESULT hres;
+
+            if(script_elem->pending_readystatechange_event)
+                return;
+
+            task = heap_alloc(sizeof(*task));
+            if(!task)
+                return;
+
+            IHTMLScriptElement_AddRef(&script_elem->IHTMLScriptElement_iface);
+            task->elem = script_elem;
+
+            hres = push_task(&task->header, fire_readystatechange_proc, fire_readystatechange_task_destr,
+                    script_elem->element.node.doc->window->task_magic);
+            if(SUCCEEDED(hres))
+                script_elem->pending_readystatechange_event = TRUE;
+        }else {
+            script_elem->pending_readystatechange_event = FALSE;
+            fire_event(script_elem->element.node.doc, EVENTID_READYSTATECHANGE, FALSE,
+                    script_elem->element.node.nsnode, NULL, NULL);
+        }
+    }
 }
 
 static void parse_elem_text(ScriptHost *script_host, HTMLScriptElement *script_elem, LPCWSTR text)




More information about the wine-cvs mailing list