Module: wine Branch: master Commit: f4b68522783a5cacb1e99d5e6a8d3015382e5dc6 URL: http://source.winehq.org/git/wine.git/?a=commit;h=f4b68522783a5cacb1e99d5e6a...
Author: Jacek Caban jacek@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)