From 5b1affa44641ac9c600d905e54cadc098659bec0 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 19 Jul 2016 18:40:36 +0200 Subject: [PATCH] mshtml: Moved script execution logic from HTMLScriptElement::put_src to script BSC. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/mshtml/htmlscript.c | 44 ++++++++--------------------- dlls/mshtml/htmlscript.h | 1 + dlls/mshtml/script.c | 60 +++++++++++++++++++++++++++++++++++----- 3 files changed, 66 insertions(+), 39 deletions(-) diff --git a/dlls/mshtml/htmlscript.c b/dlls/mshtml/htmlscript.c index 0a2d67a32f4..0d6dddfd6e8 100644 --- a/dlls/mshtml/htmlscript.c +++ b/dlls/mshtml/htmlscript.c @@ -96,20 +96,12 @@ static HRESULT WINAPI HTMLScriptElement_Invoke(IHTMLScriptElement *iface, DISPID static HRESULT WINAPI HTMLScriptElement_put_src(IHTMLScriptElement *iface, BSTR v) { HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface); - HTMLInnerWindow *window; - nsIDOMNode *parent; nsAString src_str; nsresult nsres; + HRESULT hres; TRACE("(%p)->(%s)\n", This, debugstr_w(v)); - if(!This->element.node.doc || !This->element.node.doc->window) { - WARN("no windoow\n"); - return E_UNEXPECTED; - } - - window = This->element.node.doc->window; - nsAString_InitDepend(&src_str, v); nsres = nsIDOMHTMLScriptElement_SetSrc(This->nsscript, &src_str); nsAString_Finish(&src_str); @@ -123,30 +115,18 @@ static HRESULT WINAPI HTMLScriptElement_put_src(IHTMLScriptElement *iface, BSTR return S_OK; } - if(window->parser_callback_cnt) { - 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; + nsAString_Init(&src_str, NULL); + nsres = nsIDOMHTMLScriptElement_GetSrc(This->nsscript, &src_str); + if(NS_SUCCEEDED(nsres)) { + const PRUnichar *src; + nsAString_GetData(&src_str, &src); + hres = load_script(This, src); + }else { + ERR("SetSrc failed: %08x\n", nsres); + hres = E_FAIL; } - - nsres = nsIDOMHTMLElement_GetParentNode(This->element.nselem, &parent); - if(NS_FAILED(nsres) || !parent) { - TRACE("No parent, not executing\n"); - This->parse_on_bind = TRUE; - return S_OK; - } - - nsIDOMNode_Release(parent); - doc_insert_script(window, This); - return S_OK; + nsAString_Finish(&src_str); + return hres; } static HRESULT WINAPI HTMLScriptElement_get_src(IHTMLScriptElement *iface, BSTR *p) diff --git a/dlls/mshtml/htmlscript.h b/dlls/mshtml/htmlscript.h index 4e40f63e6d5..efa392dbc8f 100644 --- a/dlls/mshtml/htmlscript.h +++ b/dlls/mshtml/htmlscript.h @@ -36,6 +36,7 @@ typedef struct { HRESULT script_elem_from_nsscript(HTMLDocumentNode*,nsIDOMHTMLScriptElement*,HTMLScriptElement**) DECLSPEC_HIDDEN; void bind_event_scripts(HTMLDocumentNode*) DECLSPEC_HIDDEN; +HRESULT load_script(HTMLScriptElement*,const WCHAR*) DECLSPEC_HIDDEN; void release_script_hosts(HTMLInnerWindow*) DECLSPEC_HIDDEN; void connect_scripts(HTMLInnerWindow*) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c index ab9be3b4419..fa1a681bb9a 100644 --- a/dlls/mshtml/script.c +++ b/dlls/mshtml/script.c @@ -866,6 +866,8 @@ static void script_file_available(ScriptBSC *bsc) HTMLScriptElement *script_elem = bsc->script_elem; HTMLInnerWindow *window = bsc->bsc.window; ScriptHost *script_host; + nsIDOMNode *parent; + nsresult nsres; HRESULT hres; assert(window != NULL); @@ -874,12 +876,42 @@ static void script_file_available(ScriptBSC *bsc) if(FAILED(hres)) return; + script_host = get_elem_script_host(window, script_elem); + if(!script_host) + return; + + if(window->parser_callback_cnt) { + script_queue_entry_t *queue; + + TRACE("Adding to queue\n"); + + queue = heap_alloc(sizeof(*queue)); + if(!queue) + return; + + IHTMLScriptElement_AddRef(&script_elem->IHTMLScriptElement_iface); + queue->script = script_elem; + + list_add_tail(&window->script_queue, &queue->entry); + return; + } + + nsres = nsIDOMHTMLElement_GetParentNode(script_elem->element.nselem, &parent); + if(NS_FAILED(nsres) || !parent) { + TRACE("No parent, not executing\n"); + script_elem->parse_on_bind = TRUE; + return; + } + + nsIDOMNode_Release(parent); + script_host = get_elem_script_host(window, script_elem); if(!script_host) return; script_elem->parsed = TRUE; - parse_elem_text(script_host, script_elem, script_elem->src_text); + if(script_host->parse) + parse_elem_text(script_host, script_elem, script_elem->src_text); } static inline ScriptBSC *impl_from_BSCallback(BSCallback *iface) @@ -997,7 +1029,7 @@ static const BSCallbackVtbl ScriptBSCVtbl = { }; -static HRESULT load_script(HTMLScriptElement *script_elem, const WCHAR *src) +HRESULT load_script(HTMLScriptElement *script_elem, const WCHAR *src) { HTMLInnerWindow *window; ScriptBSC *bsc; @@ -1066,9 +1098,10 @@ static void parse_inline_script(ScriptHost *script_host, HTMLScriptElement *scri nsAString_Finish(&text_str); } -static void parse_script_elem(ScriptHost *script_host, HTMLScriptElement *script_elem) +static BOOL parse_script_elem(ScriptHost *script_host, HTMLScriptElement *script_elem) { nsAString src_str, event_str; + BOOL is_complete = FALSE; const PRUnichar *src; nsresult nsres; @@ -1081,7 +1114,7 @@ static void parse_script_elem(ScriptHost *script_host, HTMLScriptElement *script if(*event) { TRACE("deferring event %s script evaluation\n", debugstr_w(event)); nsAString_Finish(&event_str); - return; + return FALSE; } }else { ERR("GetEvent failed: %08x\n", nsres); @@ -1096,13 +1129,15 @@ static void parse_script_elem(ScriptHost *script_host, HTMLScriptElement *script ERR("GetSrc failed: %08x\n", nsres); }else if(*src) { load_script(script_elem, src); + is_complete = script_elem->parsed; }else { parse_inline_script(script_host, script_elem); + is_complete = TRUE; } nsAString_Finish(&src_str); - set_script_elem_readystate(script_elem, READYSTATE_COMPLETE); + return is_complete; } static GUID get_default_script_guid(HTMLInnerWindow *window) @@ -1225,13 +1260,24 @@ static ScriptHost *get_elem_script_host(HTMLInnerWindow *window, HTMLScriptEleme void doc_insert_script(HTMLInnerWindow *window, HTMLScriptElement *script_elem) { ScriptHost *script_host; + BOOL is_complete = FALSE; script_host = get_elem_script_host(window, script_elem); if(!script_host) return; - if(script_host->parse) - parse_script_elem(script_host, script_elem); + if(script_host->parse) { + if(script_elem->src_text) { + script_elem->parsed = TRUE; + parse_elem_text(script_host, script_elem, script_elem->src_text); + is_complete = TRUE; + }else { + is_complete = parse_script_elem(script_host, script_elem); + } + } + + if(is_complete) + set_script_elem_readystate(script_elem, READYSTATE_COMPLETE); } IDispatch *script_parse_event(HTMLInnerWindow *window, LPCWSTR text)