Jacek Caban : mshtml: Added support for IHTMLScriptElement:: put_src calls during parser callback.

Alexandre Julliard julliard at winehq.org
Tue Oct 16 15:27:47 CDT 2012


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Oct 16 17:08:25 2012 +0200

mshtml: Added support for IHTMLScriptElement::put_src calls during parser callback.

---

 dlls/mshtml/htmlscript.c     |   13 +++++++++++--
 dlls/mshtml/htmlscript.h     |    5 +++++
 dlls/mshtml/htmlwindow.c     |    1 +
 dlls/mshtml/mshtml_private.h |    1 +
 dlls/mshtml/mutation.c       |   14 ++++++++++++++
 dlls/mshtml/script.c         |   12 ++++++++++++
 6 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/dlls/mshtml/htmlscript.c b/dlls/mshtml/htmlscript.c
index a256663..75e65f1 100644
--- a/dlls/mshtml/htmlscript.c
+++ b/dlls/mshtml/htmlscript.c
@@ -123,8 +123,17 @@ static HRESULT WINAPI HTMLScriptElement_put_src(IHTMLScriptElement *iface, BSTR
     }
 
     if(window->parser_callback_cnt) {
-        FIXME("execution inside parser not supported\n");
-        return E_NOTIMPL;
+        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;
     }
 
     nsres = nsIDOMHTMLScriptElement_GetParentNode(This->nsscript, &parent);
diff --git a/dlls/mshtml/htmlscript.h b/dlls/mshtml/htmlscript.h
index d6031bd..4540d4c 100644
--- a/dlls/mshtml/htmlscript.h
+++ b/dlls/mshtml/htmlscript.h
@@ -25,6 +25,11 @@ typedef struct {
     BOOL parsed;
 } HTMLScriptElement;
 
+typedef struct {
+    struct list entry;
+    HTMLScriptElement *script;
+} script_queue_entry_t;
+
 HRESULT script_elem_from_nsscript(HTMLDocumentNode*,nsIDOMHTMLScriptElement*,HTMLScriptElement**) DECLSPEC_HIDDEN;
 void bind_event_scripts(HTMLDocumentNode*) DECLSPEC_HIDDEN;
 
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c
index 740ac55..92659cf 100644
--- a/dlls/mshtml/htmlwindow.c
+++ b/dlls/mshtml/htmlwindow.c
@@ -2720,6 +2720,7 @@ static HRESULT create_inner_window(HTMLOuterWindow *outer_window, IMoniker *mon,
 
     list_init(&window->script_hosts);
     list_init(&window->bindings);
+    list_init(&window->script_queue);
 
     window->base.outer_window = outer_window;
     window->base.inner_window = window;
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index d5f4ce3..737731f 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -400,6 +400,7 @@ struct HTMLInnerWindow {
     IHTMLStorage *session_storage;
 
     unsigned parser_callback_cnt;
+    struct list script_queue;
 
     global_prop_t *global_props;
     DWORD global_prop_cnt;
diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c
index 3ab7a07..5e54158 100644
--- a/dlls/mshtml/mutation.c
+++ b/dlls/mshtml/mutation.c
@@ -298,6 +298,7 @@ static nsresult run_insert_script(HTMLDocumentNode *doc, nsISupports *script_ifa
     nsIDOMHTMLScriptElement *nsscript;
     HTMLScriptElement *script_elem;
     nsIParser *nsparser = NULL;
+    script_queue_entry_t *iter;
     HTMLInnerWindow *window;
     nsresult nsres;
     HRESULT hres;
@@ -332,8 +333,20 @@ static nsresult run_insert_script(HTMLDocumentNode *doc, nsISupports *script_ifa
         window->parser_callback_cnt++;
     }
 
+    IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
+
     doc_insert_script(window, script_elem);
 
+    while(!list_empty(&window->script_queue)) {
+        iter = LIST_ENTRY(list_head(&window->script_queue), script_queue_entry_t, entry);
+        list_remove(&iter->entry);
+        doc_insert_script(window, iter->script);
+        IHTMLScriptElement_Release(&iter->script->IHTMLScriptElement_iface);
+        heap_free(iter);
+    }
+
+    IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
+
     if(nsparser) {
         window->parser_callback_cnt--;
         nsIParser_EndEvaluatingParserInsertedScript(nsparser);
@@ -341,6 +354,7 @@ static nsresult run_insert_script(HTMLDocumentNode *doc, nsISupports *script_ifa
     }
 
     IHTMLScriptElement_Release(&script_elem->IHTMLScriptElement_iface);
+
     return NS_OK;
 }
 
diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c
index 730881b..d99269a 100644
--- a/dlls/mshtml/script.c
+++ b/dlls/mshtml/script.c
@@ -915,6 +915,9 @@ void doc_insert_script(HTMLInnerWindow *window, HTMLScriptElement *script_elem)
 {
     ScriptHost *script_host;
 
+    if(script_elem->parsed)
+        return;
+
     script_host = get_elem_script_host(window, script_elem);
     if(!script_host)
         return;
@@ -1309,8 +1312,17 @@ void set_script_mode(HTMLOuterWindow *window, SCRIPTMODE mode)
 
 void release_script_hosts(HTMLInnerWindow *window)
 {
+    script_queue_entry_t *queue_iter;
     ScriptHost *iter;
 
+    while(!list_empty(&window->script_queue)) {
+        queue_iter = LIST_ENTRY(list_head(&window->script_queue), script_queue_entry_t, entry);
+
+        list_remove(&queue_iter->entry);
+        IHTMLScriptElement_Release(&queue_iter->script->IHTMLScriptElement_iface);
+        heap_free(queue_iter);
+    }
+
     while(!list_empty(&window->script_hosts)) {
         iter = LIST_ENTRY(list_head(&window->script_hosts), ScriptHost, entry);
 




More information about the wine-cvs mailing list