From b1f4bf1d7d0eb8368d0c9f37e02aa83c1b3d9526 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 19 Jul 2016 18:42:06 +0200 Subject: [PATCH] mshtml: Load dynamically created script elements asynchronously. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/mshtml/htmlscript.c | 7 ++++++- dlls/mshtml/htmlscript.h | 3 ++- dlls/mshtml/script.c | 16 ++++++++++------ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/dlls/mshtml/htmlscript.c b/dlls/mshtml/htmlscript.c index d2662767ece..d17884a4a67 100644 --- a/dlls/mshtml/htmlscript.c +++ b/dlls/mshtml/htmlscript.c @@ -115,12 +115,17 @@ static HRESULT WINAPI HTMLScriptElement_put_src(IHTMLScriptElement *iface, BSTR return S_OK; } + if(This->binding) { + FIXME("binding in progress\n"); + return E_FAIL; + } + 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); + hres = load_script(This, src, TRUE); }else { ERR("SetSrc failed: %08x\n", nsres); hres = E_FAIL; diff --git a/dlls/mshtml/htmlscript.h b/dlls/mshtml/htmlscript.h index f5053ee8905..3d41a6c62d1 100644 --- a/dlls/mshtml/htmlscript.h +++ b/dlls/mshtml/htmlscript.h @@ -27,6 +27,7 @@ typedef struct { BOOL pending_readystatechange_event; READYSTATE readystate; WCHAR *src_text; /* sctipt text downloaded from src */ + BSCallback *binding; /* weak reference to current binding */ } HTMLScriptElement; typedef struct { @@ -36,7 +37,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; +HRESULT load_script(HTMLScriptElement*,const WCHAR*,BOOL) 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 bd0f8d4c63e..40deda4e9a6 100644 --- a/dlls/mshtml/script.c +++ b/dlls/mshtml/script.c @@ -796,7 +796,6 @@ static void parse_elem_text(ScriptHost *script_host, HTMLScriptElement *script_e TRACE("<<<\n"); else WARN("<<< %08x\n", hres); - } typedef struct { @@ -939,6 +938,8 @@ static HRESULT ScriptBSC_start_binding(BSCallback *bsc) { ScriptBSC *This = impl_from_BSCallback(bsc); + This->script_elem->binding = &This->bsc; + /* FIXME: We should find a better to decide if 'loading' state is supposed to be used by the protocol. */ if(This->scheme == URL_SCHEME_HTTPS || This->scheme == URL_SCHEME_HTTP) set_script_elem_readystate(This->script_elem, READYSTATE_LOADING); @@ -953,6 +954,9 @@ static HRESULT ScriptBSC_stop_binding(BSCallback *bsc, HRESULT result) if(SUCCEEDED(result) && !This->script_elem) result = E_UNEXPECTED; + assert(FAILED(result) || This->script_elem->binding == &This->bsc); + This->script_elem->binding = NULL; + if(This->script_elem->readystate == READYSTATE_LOADING) set_script_elem_readystate(This->script_elem, READYSTATE_LOADED); @@ -1027,7 +1031,7 @@ static const BSCallbackVtbl ScriptBSCVtbl = { }; -HRESULT load_script(HTMLScriptElement *script_elem, const WCHAR *src) +HRESULT load_script(HTMLScriptElement *script_elem, const WCHAR *src, BOOL async) { HTMLInnerWindow *window; ScriptBSC *bsc; @@ -1040,7 +1044,7 @@ HRESULT load_script(HTMLScriptElement *script_elem, const WCHAR *src) if(strlenW(src) > sizeof(wine_schemaW)/sizeof(WCHAR) && !memcmp(src, wine_schemaW, sizeof(wine_schemaW))) src += sizeof(wine_schemaW)/sizeof(WCHAR); - TRACE("(%p %s)\n", script_elem, debugstr_w(src)); + TRACE("(%p %s %x)\n", script_elem, debugstr_w(src), async); if(!script_elem->element.node.doc || !(window = script_elem->element.node.doc->window)) { ERR("no window\n"); @@ -1061,7 +1065,7 @@ HRESULT load_script(HTMLScriptElement *script_elem, const WCHAR *src) return E_OUTOFMEMORY; } - init_bscallback(&bsc->bsc, &ScriptBSCVtbl, mon, 0); + init_bscallback(&bsc->bsc, &ScriptBSCVtbl, mon, async ? BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA : 0); IMoniker_Release(mon); hres = IUri_GetScheme(uri, &bsc->scheme); @@ -1128,7 +1132,7 @@ static BOOL parse_script_elem(ScriptHost *script_host, HTMLScriptElement *script if(NS_FAILED(nsres)) { ERR("GetSrc failed: %08x\n", nsres); }else if(*src) { - load_script(script_elem, src); + load_script(script_elem, src, FALSE); is_complete = script_elem->parsed; }else { parse_inline_script(script_host, script_elem); @@ -1273,7 +1277,7 @@ void doc_insert_script(HTMLInnerWindow *window, HTMLScriptElement *script_elem, script_elem->parsed = TRUE; parse_elem_text(script_host, script_elem, script_elem->src_text); is_complete = TRUE; - }else { + }else if(!script_elem->binding) { is_complete = parse_script_elem(script_host, script_elem); } }