Jacek Caban : mshtml: Load dynamically created script elements asynchronously.

Alexandre Julliard julliard at winehq.org
Wed Jul 20 10:28:51 CDT 2016


Module: wine
Branch: master
Commit: b1f4bf1d7d0eb8368d0c9f37e02aa83c1b3d9526
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b1f4bf1d7d0eb8368d0c9f37e02aa83c1b3d9526

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Jul 19 18:42:06 2016 +0200

mshtml: Load dynamically created script elements asynchronously.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 d266276..d17884a 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 f5053ee..3d41a6c 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 bd0f8d4..40deda4 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);
         }
     }




More information about the wine-cvs mailing list