mshtml: Load dynamically created script elements asynchronously.

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:42:06 +02:00 committed by Alexandre Julliard
parent 8ccc38cb55
commit b1f4bf1d7d
3 changed files with 18 additions and 8 deletions

View File

@ -115,12 +115,17 @@ static HRESULT WINAPI HTMLScriptElement_put_src(IHTMLScriptElement *iface, BSTR
return S_OK; return S_OK;
} }
if(This->binding) {
FIXME("binding in progress\n");
return E_FAIL;
}
nsAString_Init(&src_str, NULL); nsAString_Init(&src_str, NULL);
nsres = nsIDOMHTMLScriptElement_GetSrc(This->nsscript, &src_str); nsres = nsIDOMHTMLScriptElement_GetSrc(This->nsscript, &src_str);
if(NS_SUCCEEDED(nsres)) { if(NS_SUCCEEDED(nsres)) {
const PRUnichar *src; const PRUnichar *src;
nsAString_GetData(&src_str, &src); nsAString_GetData(&src_str, &src);
hres = load_script(This, src); hres = load_script(This, src, TRUE);
}else { }else {
ERR("SetSrc failed: %08x\n", nsres); ERR("SetSrc failed: %08x\n", nsres);
hres = E_FAIL; hres = E_FAIL;

View File

@ -27,6 +27,7 @@ typedef struct {
BOOL pending_readystatechange_event; BOOL pending_readystatechange_event;
READYSTATE readystate; READYSTATE readystate;
WCHAR *src_text; /* sctipt text downloaded from src */ WCHAR *src_text; /* sctipt text downloaded from src */
BSCallback *binding; /* weak reference to current binding */
} HTMLScriptElement; } HTMLScriptElement;
typedef struct { typedef struct {
@ -36,7 +37,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; HRESULT load_script(HTMLScriptElement*,const WCHAR*,BOOL) 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

@ -796,7 +796,6 @@ static void parse_elem_text(ScriptHost *script_host, HTMLScriptElement *script_e
TRACE("<<<\n"); TRACE("<<<\n");
else else
WARN("<<< %08x\n", hres); WARN("<<< %08x\n", hres);
} }
typedef struct { typedef struct {
@ -939,6 +938,8 @@ static HRESULT ScriptBSC_start_binding(BSCallback *bsc)
{ {
ScriptBSC *This = impl_from_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. */ /* 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) if(This->scheme == URL_SCHEME_HTTPS || This->scheme == URL_SCHEME_HTTP)
set_script_elem_readystate(This->script_elem, READYSTATE_LOADING); 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) if(SUCCEEDED(result) && !This->script_elem)
result = E_UNEXPECTED; result = E_UNEXPECTED;
assert(FAILED(result) || This->script_elem->binding == &This->bsc);
This->script_elem->binding = NULL;
if(This->script_elem->readystate == READYSTATE_LOADING) if(This->script_elem->readystate == READYSTATE_LOADING)
set_script_elem_readystate(This->script_elem, READYSTATE_LOADED); 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; HTMLInnerWindow *window;
ScriptBSC *bsc; 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))) if(strlenW(src) > sizeof(wine_schemaW)/sizeof(WCHAR) && !memcmp(src, wine_schemaW, sizeof(wine_schemaW)))
src += sizeof(wine_schemaW)/sizeof(WCHAR); 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)) { if(!script_elem->element.node.doc || !(window = script_elem->element.node.doc->window)) {
ERR("no window\n"); ERR("no window\n");
@ -1061,7 +1065,7 @@ HRESULT load_script(HTMLScriptElement *script_elem, const WCHAR *src)
return E_OUTOFMEMORY; 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); IMoniker_Release(mon);
hres = IUri_GetScheme(uri, &bsc->scheme); hres = IUri_GetScheme(uri, &bsc->scheme);
@ -1128,7 +1132,7 @@ static BOOL parse_script_elem(ScriptHost *script_host, HTMLScriptElement *script
if(NS_FAILED(nsres)) { if(NS_FAILED(nsres)) {
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, FALSE);
is_complete = script_elem->parsed; is_complete = script_elem->parsed;
}else { }else {
parse_inline_script(script_host, script_elem); parse_inline_script(script_host, script_elem);
@ -1273,7 +1277,7 @@ void doc_insert_script(HTMLInnerWindow *window, HTMLScriptElement *script_elem,
script_elem->parsed = TRUE; script_elem->parsed = TRUE;
parse_elem_text(script_host, script_elem, script_elem->src_text); parse_elem_text(script_host, script_elem, script_elem->src_text);
is_complete = TRUE; is_complete = TRUE;
}else { }else if(!script_elem->binding) {
is_complete = parse_script_elem(script_host, script_elem); is_complete = parse_script_elem(script_host, script_elem);
} }
} }