Module: wine Branch: master Commit: ccbee09f7ea340d3b2185cd2c4e6a470f8dab656 URL: http://source.winehq.org/git/wine.git/?a=commit;h=ccbee09f7ea340d3b2185cd2c4...
Author: Jacek Caban jacek@codeweavers.com Date: Tue Oct 16 17:08:25 2012 +0200
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 a256663..75e65f1 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 d6031bd..4540d4c 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 740ac55..92659cf 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 d5f4ce3..737731f 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 3ab7a07..5e54158 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 730881b..d99269a 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);