mshtml: Moved script execution logic from HTMLScriptElement::put_src to script BSC.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2016-07-19 18:40:36 +02:00 committed by Alexandre Julliard
parent eeb075dd0e
commit 5b1affa446
3 changed files with 66 additions and 39 deletions

View File

@ -96,20 +96,12 @@ static HRESULT WINAPI HTMLScriptElement_Invoke(IHTMLScriptElement *iface, DISPID
static HRESULT WINAPI HTMLScriptElement_put_src(IHTMLScriptElement *iface, BSTR v) static HRESULT WINAPI HTMLScriptElement_put_src(IHTMLScriptElement *iface, BSTR v)
{ {
HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface); HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
HTMLInnerWindow *window;
nsIDOMNode *parent;
nsAString src_str; nsAString src_str;
nsresult nsres; nsresult nsres;
HRESULT hres;
TRACE("(%p)->(%s)\n", This, debugstr_w(v)); 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); nsAString_InitDepend(&src_str, v);
nsres = nsIDOMHTMLScriptElement_SetSrc(This->nsscript, &src_str); nsres = nsIDOMHTMLScriptElement_SetSrc(This->nsscript, &src_str);
nsAString_Finish(&src_str); nsAString_Finish(&src_str);
@ -123,30 +115,18 @@ static HRESULT WINAPI HTMLScriptElement_put_src(IHTMLScriptElement *iface, BSTR
return S_OK; return S_OK;
} }
if(window->parser_callback_cnt) { nsAString_Init(&src_str, NULL);
script_queue_entry_t *queue; nsres = nsIDOMHTMLScriptElement_GetSrc(This->nsscript, &src_str);
if(NS_SUCCEEDED(nsres)) {
queue = heap_alloc(sizeof(*queue)); const PRUnichar *src;
if(!queue) nsAString_GetData(&src_str, &src);
return E_OUTOFMEMORY; hres = load_script(This, src);
}else {
IHTMLScriptElement_AddRef(&This->IHTMLScriptElement_iface); ERR("SetSrc failed: %08x\n", nsres);
queue->script = This; hres = E_FAIL;
list_add_tail(&window->script_queue, &queue->entry);
return S_OK;
} }
nsAString_Finish(&src_str);
nsres = nsIDOMHTMLElement_GetParentNode(This->element.nselem, &parent); return hres;
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;
} }
static HRESULT WINAPI HTMLScriptElement_get_src(IHTMLScriptElement *iface, BSTR *p) static HRESULT WINAPI HTMLScriptElement_get_src(IHTMLScriptElement *iface, BSTR *p)

View File

@ -36,6 +36,7 @@ typedef struct {
HRESULT script_elem_from_nsscript(HTMLDocumentNode*,nsIDOMHTMLScriptElement*,HTMLScriptElement**) DECLSPEC_HIDDEN; HRESULT script_elem_from_nsscript(HTMLDocumentNode*,nsIDOMHTMLScriptElement*,HTMLScriptElement**) DECLSPEC_HIDDEN;
void bind_event_scripts(HTMLDocumentNode*) 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 release_script_hosts(HTMLInnerWindow*) DECLSPEC_HIDDEN;
void connect_scripts(HTMLInnerWindow*) DECLSPEC_HIDDEN; void connect_scripts(HTMLInnerWindow*) DECLSPEC_HIDDEN;

View File

@ -866,6 +866,8 @@ static void script_file_available(ScriptBSC *bsc)
HTMLScriptElement *script_elem = bsc->script_elem; HTMLScriptElement *script_elem = bsc->script_elem;
HTMLInnerWindow *window = bsc->bsc.window; HTMLInnerWindow *window = bsc->bsc.window;
ScriptHost *script_host; ScriptHost *script_host;
nsIDOMNode *parent;
nsresult nsres;
HRESULT hres; HRESULT hres;
assert(window != NULL); assert(window != NULL);
@ -874,12 +876,42 @@ static void script_file_available(ScriptBSC *bsc)
if(FAILED(hres)) if(FAILED(hres))
return; 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); script_host = get_elem_script_host(window, script_elem);
if(!script_host) if(!script_host)
return; return;
script_elem->parsed = TRUE; 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) 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; HTMLInnerWindow *window;
ScriptBSC *bsc; ScriptBSC *bsc;
@ -1066,9 +1098,10 @@ static void parse_inline_script(ScriptHost *script_host, HTMLScriptElement *scri
nsAString_Finish(&text_str); 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; nsAString src_str, event_str;
BOOL is_complete = FALSE;
const PRUnichar *src; const PRUnichar *src;
nsresult nsres; nsresult nsres;
@ -1081,7 +1114,7 @@ static void parse_script_elem(ScriptHost *script_host, HTMLScriptElement *script
if(*event) { if(*event) {
TRACE("deferring event %s script evaluation\n", debugstr_w(event)); TRACE("deferring event %s script evaluation\n", debugstr_w(event));
nsAString_Finish(&event_str); nsAString_Finish(&event_str);
return; return FALSE;
} }
}else { }else {
ERR("GetEvent failed: %08x\n", nsres); 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); ERR("GetSrc failed: %08x\n", nsres);
}else if(*src) { }else if(*src) {
load_script(script_elem, src); load_script(script_elem, src);
is_complete = script_elem->parsed;
}else { }else {
parse_inline_script(script_host, script_elem); parse_inline_script(script_host, script_elem);
is_complete = TRUE;
} }
nsAString_Finish(&src_str); nsAString_Finish(&src_str);
set_script_elem_readystate(script_elem, READYSTATE_COMPLETE); return is_complete;
} }
static GUID get_default_script_guid(HTMLInnerWindow *window) 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) void doc_insert_script(HTMLInnerWindow *window, HTMLScriptElement *script_elem)
{ {
ScriptHost *script_host; ScriptHost *script_host;
BOOL is_complete = FALSE;
script_host = get_elem_script_host(window, script_elem); script_host = get_elem_script_host(window, script_elem);
if(!script_host) if(!script_host)
return; return;
if(script_host->parse) if(script_host->parse) {
parse_script_elem(script_host, script_elem); 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) IDispatch *script_parse_event(HTMLInnerWindow *window, LPCWSTR text)