From ccbee09f7ea340d3b2185cd2c4e6a470f8dab656 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 16 Oct 2012 17:08:25 +0200 Subject: [PATCH] mshtml: Added support for IHTMLScriptElement::put_src calls during parser callback. --- dlls/mshtml/htmlscript.c | 13 +++++++++++-- dlls/mshtml/htmlscript.h | 5 +++++ dlls/mshtml/htmlwindow.c | 1 + dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/mutation.c | 14 ++++++++++++++ dlls/mshtml/script.c | 12 ++++++++++++ 6 files changed, 44 insertions(+), 2 deletions(-) diff --git a/dlls/mshtml/htmlscript.c b/dlls/mshtml/htmlscript.c index a256663c66e..75e65f1bdd9 100644 --- a/dlls/mshtml/htmlscript.c +++ b/dlls/mshtml/htmlscript.c @@ -123,8 +123,17 @@ static HRESULT WINAPI HTMLScriptElement_put_src(IHTMLScriptElement *iface, BSTR } if(window->parser_callback_cnt) { - FIXME("execution inside parser not supported\n"); - return E_NOTIMPL; + script_queue_entry_t *queue; + + queue = heap_alloc(sizeof(*queue)); + if(!queue) + return E_OUTOFMEMORY; + + IHTMLScriptElement_AddRef(&This->IHTMLScriptElement_iface); + queue->script = This; + + list_add_tail(&window->script_queue, &queue->entry); + return S_OK; } nsres = nsIDOMHTMLScriptElement_GetParentNode(This->nsscript, &parent); diff --git a/dlls/mshtml/htmlscript.h b/dlls/mshtml/htmlscript.h index d6031bd66ed..4540d4c3412 100644 --- a/dlls/mshtml/htmlscript.h +++ b/dlls/mshtml/htmlscript.h @@ -25,6 +25,11 @@ typedef struct { BOOL parsed; } HTMLScriptElement; +typedef struct { + struct list entry; + HTMLScriptElement *script; +} script_queue_entry_t; + HRESULT script_elem_from_nsscript(HTMLDocumentNode*,nsIDOMHTMLScriptElement*,HTMLScriptElement**) DECLSPEC_HIDDEN; void bind_event_scripts(HTMLDocumentNode*) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 740ac556441..92659cf66b3 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -2720,6 +2720,7 @@ static HRESULT create_inner_window(HTMLOuterWindow *outer_window, IMoniker *mon, list_init(&window->script_hosts); list_init(&window->bindings); + list_init(&window->script_queue); window->base.outer_window = outer_window; window->base.inner_window = window; diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index d5f4ce3452b..737731fa01c 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -400,6 +400,7 @@ struct HTMLInnerWindow { IHTMLStorage *session_storage; unsigned parser_callback_cnt; + struct list script_queue; global_prop_t *global_props; DWORD global_prop_cnt; diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c index 3ab7a072add..5e541586a62 100644 --- a/dlls/mshtml/mutation.c +++ b/dlls/mshtml/mutation.c @@ -298,6 +298,7 @@ static nsresult run_insert_script(HTMLDocumentNode *doc, nsISupports *script_ifa nsIDOMHTMLScriptElement *nsscript; HTMLScriptElement *script_elem; nsIParser *nsparser = NULL; + script_queue_entry_t *iter; HTMLInnerWindow *window; nsresult nsres; HRESULT hres; @@ -332,8 +333,20 @@ static nsresult run_insert_script(HTMLDocumentNode *doc, nsISupports *script_ifa window->parser_callback_cnt++; } + IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface); + doc_insert_script(window, script_elem); + while(!list_empty(&window->script_queue)) { + iter = LIST_ENTRY(list_head(&window->script_queue), script_queue_entry_t, entry); + list_remove(&iter->entry); + doc_insert_script(window, iter->script); + IHTMLScriptElement_Release(&iter->script->IHTMLScriptElement_iface); + heap_free(iter); + } + + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + if(nsparser) { window->parser_callback_cnt--; nsIParser_EndEvaluatingParserInsertedScript(nsparser); @@ -341,6 +354,7 @@ static nsresult run_insert_script(HTMLDocumentNode *doc, nsISupports *script_ifa } IHTMLScriptElement_Release(&script_elem->IHTMLScriptElement_iface); + return NS_OK; } diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c index 730881b283b..d99269ae2e2 100644 --- a/dlls/mshtml/script.c +++ b/dlls/mshtml/script.c @@ -915,6 +915,9 @@ void doc_insert_script(HTMLInnerWindow *window, HTMLScriptElement *script_elem) { ScriptHost *script_host; + if(script_elem->parsed) + return; + script_host = get_elem_script_host(window, script_elem); if(!script_host) return; @@ -1309,8 +1312,17 @@ void set_script_mode(HTMLOuterWindow *window, SCRIPTMODE mode) void release_script_hosts(HTMLInnerWindow *window) { + script_queue_entry_t *queue_iter; ScriptHost *iter; + while(!list_empty(&window->script_queue)) { + queue_iter = LIST_ENTRY(list_head(&window->script_queue), script_queue_entry_t, entry); + + list_remove(&queue_iter->entry); + IHTMLScriptElement_Release(&queue_iter->script->IHTMLScriptElement_iface); + heap_free(queue_iter); + } + while(!list_empty(&window->script_hosts)) { iter = LIST_ENTRY(list_head(&window->script_hosts), ScriptHost, entry);