From: Jacek Caban Subject: [PATCH 4/4] mshtml: Added support for target attribute in submit function implementation. Message-Id: <5321AF07.5050006@codeweavers.com> Date: Thu, 13 Mar 2014 14:13:43 +0100 --- 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..7e9beb5 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) || !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;