Jacek Caban : mshtml: Added support for target attribute in submit function implementation.

Alexandre Julliard julliard at winehq.org
Thu Mar 13 14:40:35 CDT 2014


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Mar 13 14:47:14 2014 +0100

mshtml: Added support for target attribute in submit function implementation.

---

 dlls/mshtml/htmlanchor.c     |   95 +++++++++++++++++++++++++++---------------
 dlls/mshtml/htmlform.c       |   22 ++++++++--
 dlls/mshtml/mshtml_private.h |    1 +
 3 files changed, 81 insertions(+), 37 deletions(-)

diff --git a/dlls/mshtml/htmlanchor.c b/dlls/mshtml/htmlanchor.c
index f177ff2..a9187a4 100644
--- a/dlls/mshtml/htmlanchor.c
+++ b/dlls/mshtml/htmlanchor.c
@@ -70,51 +70,81 @@ static HRESULT navigate_anchor_window(HTMLAnchorElement *This, const WCHAR *targ
     return hres;
 }
 
+HTMLOuterWindow *get_target_window(HTMLOuterWindow *window, nsAString *target_str, BOOL *use_new_window)
+{
+    HTMLOuterWindow *top_window, *ret_window;
+    const PRUnichar *target;
+    HRESULT hres;
+
+    static const WCHAR _parentW[] = {'_','p','a','r','e','n','t',0};
+    static const WCHAR _selfW[] = {'_','s','e','l','f',0};
+    static const WCHAR _topW[] = {'_','t','o','p',0};
+
+    *use_new_window = FALSE;
+
+    nsAString_GetData(target_str, &target);
+    TRACE("%s\n", debugstr_w(target));
+
+    if(!*target || !strcmpiW(target, _selfW)) {
+        IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
+        return window;
+    }
+
+    if(!strcmpiW(target, _topW)) {
+        get_top_window(window, &top_window);
+        IHTMLWindow2_AddRef(&top_window->base.IHTMLWindow2_iface);
+        return top_window;
+    }
+
+    if(!strcmpiW(target, _parentW)) {
+        if(!window->parent) {
+            WARN("Window has no parent\n");
+            return NULL;
+        }
+
+        IHTMLWindow2_AddRef(&window->parent->base.IHTMLWindow2_iface);
+        return window->parent;
+    }
+
+    get_top_window(window, &top_window);
+
+    hres = get_frame_by_name(top_window, target, TRUE, &ret_window);
+    if(FAILED(hres) || !ret_window) {
+        *use_new_window = TRUE;
+        return NULL;
+    }
+
+    IHTMLWindow2_AddRef(&ret_window->base.IHTMLWindow2_iface);
+    return ret_window;
+}
+
 static HRESULT navigate_anchor(HTMLAnchorElement *This)
 {
     nsAString href_str, target_str;
-    HTMLOuterWindow *window = NULL;
+    HTMLOuterWindow *window;
+    BOOL use_new_window;
     nsresult nsres;
     HRESULT hres = E_FAIL;
 
-    static const WCHAR _parentW[] = {'_','p','a','r','e','n','t',0};
-    static const WCHAR _selfW[] = {'_','s','e','l','f',0};
-    static const WCHAR _topW[] = {'_','t','o','p',0};
 
     nsAString_Init(&target_str, NULL);
     nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str);
-    if(NS_SUCCEEDED(nsres)) {
+    if(NS_FAILED(nsres))
+        return E_FAIL;
+
+    window = get_target_window(This->element.node.doc->basedoc.window, &target_str, &use_new_window);
+    if(!window && use_new_window) {
         const PRUnichar *target;
 
         nsAString_GetData(&target_str, &target);
-        TRACE("target %s\n", debugstr_w(target));
-        if(*target && strcmpiW(target, _selfW)) {
-            if(!strcmpiW(target, _topW)) {
-                TRACE("target _top\n");
-                get_top_window(This->element.node.doc->basedoc.window, &window);
-            }else if(!strcmpiW(target, _parentW)) {
-                window = This->element.node.doc->basedoc.window;
-                if(!window->parent) {
-                    WARN("Window has no parent\n");
-                    nsAString_Finish(&target_str);
-                    return S_OK;
-                }
-                window = window->parent;
-            }else {
-                HTMLOuterWindow *top_window;
-
-                get_top_window(This->element.node.doc->basedoc.window, &top_window);
-
-                hres = get_frame_by_name(top_window, target, TRUE, &window);
-                if(FAILED(hres) || !window) {
-                    hres = navigate_anchor_window(This, target);
-                    nsAString_Finish(&target_str);
-                    return hres;
-                }
-            }
-        }
+        hres = navigate_anchor_window(This, target);
+        nsAString_Finish(&target_str);
+        return hres;
     }
+
     nsAString_Finish(&target_str);
+    if(!window)
+        return S_OK;
 
     nsAString_Init(&href_str, NULL);
     nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str);
@@ -123,8 +153,6 @@ static HRESULT navigate_anchor(HTMLAnchorElement *This)
 
         nsAString_GetData(&href_str, &href);
         if(*href) {
-            if(!window)
-                window = This->element.node.doc->basedoc.window;
             hres = navigate_url(window, href, window->uri_nofrag, BINDING_NAVIGATED);
         }else {
             TRACE("empty href\n");
@@ -132,6 +160,7 @@ static HRESULT navigate_anchor(HTMLAnchorElement *This)
         }
     }
     nsAString_Finish(&href_str);
+    IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
     return hres;
 }
 
diff --git a/dlls/mshtml/htmlform.c b/dlls/mshtml/htmlform.c
index 65db2b2..5b9982c 100644
--- a/dlls/mshtml/htmlform.c
+++ b/dlls/mshtml/htmlform.c
@@ -362,9 +362,9 @@ static HRESULT WINAPI HTMLFormElement_get_onreset(IHTMLFormElement *iface, VARIA
 static HRESULT WINAPI HTMLFormElement_submit(IHTMLFormElement *iface)
 {
     HTMLFormElement *This = impl_from_IHTMLFormElement(iface);
-    HTMLOuterWindow *window = NULL;
+    HTMLOuterWindow *window = NULL, *this_window = NULL;
     nsIInputStream *post_stream;
-    nsAString action_uri_str;
+    nsAString action_uri_str, target_str;
     IUri *uri;
     nsresult nsres;
     HRESULT hres;
@@ -374,19 +374,32 @@ static HRESULT WINAPI HTMLFormElement_submit(IHTMLFormElement *iface)
     if(This->element.node.doc) {
         HTMLDocumentNode *doc = This->element.node.doc;
         if(doc->window && doc->window->base.outer_window)
-            window = doc->window->base.outer_window;
+            this_window = doc->window->base.outer_window;
     }
-    if(!window) {
+    if(!this_window) {
         TRACE("No outer window\n");
         return S_OK;
     }
 
+    nsAString_Init(&target_str, NULL);
+    nsres = nsIDOMHTMLFormElement_GetTarget(This->nsform, &target_str);
+    if(NS_SUCCEEDED(nsres)) {
+        BOOL use_new_window;
+        window = get_target_window(this_window, &target_str, &use_new_window);
+        if(use_new_window)
+            FIXME("submit to new window is not supported\n");
+    }
+    nsAString_Finish(&target_str);
+    if(!window)
+        return S_OK;
+
     /*
      * FIXME: We currently don't use our submit implementation for sub-windows because
      * load_nsuri can't support post data. We should fix it.
      */
     if(!window->doc_obj || window->doc_obj->basedoc.window != window) {
         nsres = nsIDOMHTMLFormElement_Submit(This->nsform);
+        IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
         if(NS_FAILED(nsres)) {
             ERR("Submit failed: %08x\n", nsres);
             return E_FAIL;
@@ -414,6 +427,7 @@ static HRESULT WINAPI HTMLFormElement_submit(IHTMLFormElement *iface)
         IUri_Release(uri);
     }
 
+    IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
     if(post_stream)
         nsIInputStream_Release(post_stream);
     return hres;
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 5907ec1..882f859 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -943,6 +943,7 @@ HTMLElement *unsafe_impl_from_IHTMLElement(IHTMLElement*) DECLSPEC_HIDDEN;
 HRESULT search_window_props(HTMLInnerWindow*,BSTR,DWORD,DISPID*) DECLSPEC_HIDDEN;
 HRESULT get_frame_by_name(HTMLOuterWindow*,const WCHAR*,BOOL,HTMLOuterWindow**) DECLSPEC_HIDDEN;
 HRESULT get_doc_elem_by_id(HTMLDocumentNode*,const WCHAR*,HTMLElement**) DECLSPEC_HIDDEN;
+HTMLOuterWindow *get_target_window(HTMLOuterWindow*,nsAString*,BOOL*) DECLSPEC_HIDDEN;
 
 HRESULT wrap_iface(IUnknown*,IUnknown*,IUnknown**) DECLSPEC_HIDDEN;
 




More information about the wine-cvs mailing list