mshtml: Try to not use nsIDOMHTMLFormElement::Submit for IHTMLFormElelement::submit implementation.
This commit is contained in:
parent
5c7c954658
commit
e61de218ee
|
@ -106,6 +106,7 @@ typedef struct {
|
|||
#define BINDING_REPLACE 0x0002
|
||||
#define BINDING_FROMHIST 0x0004
|
||||
#define BINDING_REFRESH 0x0008
|
||||
#define BINDING_SUBMIT 0x0010
|
||||
|
||||
HRESULT set_http_header(struct list*,const WCHAR*,int,const WCHAR*,int) DECLSPEC_HIDDEN;
|
||||
HRESULT create_redirect_nschannel(const WCHAR*,nsChannel*,nsChannel**) DECLSPEC_HIDDEN;
|
||||
|
@ -120,6 +121,7 @@ HRESULT super_navigate(HTMLOuterWindow*,IUri*,DWORD,const WCHAR*,BYTE*,DWORD) DE
|
|||
HRESULT load_uri(HTMLOuterWindow*,IUri*,DWORD) DECLSPEC_HIDDEN;
|
||||
HRESULT navigate_new_window(HTMLOuterWindow*,IUri*,const WCHAR*,IHTMLWindow2**) DECLSPEC_HIDDEN;
|
||||
HRESULT navigate_url(HTMLOuterWindow*,const WCHAR*,IUri*,DWORD) DECLSPEC_HIDDEN;
|
||||
HRESULT submit_form(HTMLOuterWindow*,IUri*,nsIInputStream*) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT create_channelbsc(IMoniker*,const WCHAR*,BYTE*,DWORD,BOOL,nsChannelBSC**) DECLSPEC_HIDDEN;
|
||||
HRESULT channelbsc_load_stream(HTMLInnerWindow*,IMoniker*,IStream*) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "mshtml_private.h"
|
||||
#include "htmlevent.h"
|
||||
#include "binding.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
|
||||
|
||||
|
@ -361,17 +362,61 @@ 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;
|
||||
nsIInputStream *post_stream;
|
||||
nsAString action_uri_str;
|
||||
IUri *uri;
|
||||
nsresult nsres;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p)->()\n", This);
|
||||
|
||||
nsres = nsIDOMHTMLFormElement_Submit(This->nsform);
|
||||
if(NS_FAILED(nsres)) {
|
||||
ERR("Submit failed: %08x\n", nsres);
|
||||
return E_FAIL;
|
||||
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;
|
||||
}
|
||||
if(!window) {
|
||||
TRACE("No outer window\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
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);
|
||||
if(NS_FAILED(nsres)) {
|
||||
ERR("Submit failed: %08x\n", nsres);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
nsAString_Init(&action_uri_str, NULL);
|
||||
nsres = nsIDOMHTMLFormElement_GetFormData(This->nsform, NULL, &action_uri_str, &post_stream);
|
||||
if(NS_SUCCEEDED(nsres)) {
|
||||
const PRUnichar *action_uri;
|
||||
|
||||
nsAString_GetData(&action_uri_str, &action_uri);
|
||||
hres = create_uri(action_uri, 0, &uri);
|
||||
}else {
|
||||
ERR("GetFormData failed: %08x\n", nsres);
|
||||
hres = E_FAIL;
|
||||
}
|
||||
nsAString_Finish(&action_uri_str);
|
||||
if(SUCCEEDED(hres)) {
|
||||
window->readystate_locked++;
|
||||
hres = submit_form(window, uri, post_stream);
|
||||
window->readystate_locked--;
|
||||
IUri_Release(uri);
|
||||
}
|
||||
|
||||
if(post_stream)
|
||||
nsIInputStream_Release(post_stream);
|
||||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HTMLFormElement_reset(IHTMLFormElement *iface)
|
||||
|
|
|
@ -385,7 +385,10 @@ struct HTMLOuterWindow {
|
|||
nsIDOMWindow *nswindow;
|
||||
HTMLOuterWindow *parent;
|
||||
HTMLFrameBase *frame_element;
|
||||
|
||||
READYSTATE readystate;
|
||||
BOOL readystate_locked;
|
||||
unsigned readystate_pending;
|
||||
|
||||
HTMLInnerWindow *pending_window;
|
||||
IMoniker *mon;
|
||||
|
|
|
@ -2238,7 +2238,32 @@ HRESULT super_navigate(HTMLOuterWindow *window, IUri *uri, DWORD flags, const WC
|
|||
prepare_for_binding(&window->doc_obj->basedoc, mon, flags);
|
||||
|
||||
hres = IUri_GetScheme(uri, &scheme);
|
||||
if(SUCCEEDED(hres) && scheme != URL_SCHEME_JAVASCRIPT) {
|
||||
if(SUCCEEDED(hres) && scheme == URL_SCHEME_JAVASCRIPT) {
|
||||
navigate_javascript_task_t *task;
|
||||
|
||||
IBindStatusCallback_Release(&bsc->bsc.IBindStatusCallback_iface);
|
||||
IMoniker_Release(mon);
|
||||
|
||||
task = heap_alloc(sizeof(*task));
|
||||
if(!task)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
/* Why silently? */
|
||||
window->readystate = READYSTATE_COMPLETE;
|
||||
if(!(flags & BINDING_FROMHIST))
|
||||
call_docview_84(window->doc_obj);
|
||||
|
||||
IUri_AddRef(uri);
|
||||
task->window = window;
|
||||
task->uri = uri;
|
||||
hres = push_task(&task->header, navigate_javascript_proc, navigate_javascript_task_destr, window->task_magic);
|
||||
}else if(flags & BINDING_SUBMIT) {
|
||||
hres = set_moniker(window, mon, uri, NULL, bsc, TRUE);
|
||||
if(SUCCEEDED(hres))
|
||||
hres = start_binding(window->pending_window, &bsc->bsc, NULL);
|
||||
IBindStatusCallback_Release(&bsc->bsc.IBindStatusCallback_iface);
|
||||
IMoniker_Release(mon);
|
||||
}else {
|
||||
navigate_task_t *task;
|
||||
|
||||
task = heap_alloc(sizeof(*task));
|
||||
|
@ -2261,25 +2286,6 @@ HRESULT super_navigate(HTMLOuterWindow *window, IUri *uri, DWORD flags, const WC
|
|||
IUri_AddRef(uri);
|
||||
task->uri = uri;
|
||||
hres = push_task(&task->header, navigate_proc, navigate_task_destr, window->task_magic);
|
||||
}else {
|
||||
navigate_javascript_task_t *task;
|
||||
|
||||
IBindStatusCallback_Release(&bsc->bsc.IBindStatusCallback_iface);
|
||||
IMoniker_Release(mon);
|
||||
|
||||
task = heap_alloc(sizeof(*task));
|
||||
if(!task)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
/* Why silently? */
|
||||
window->readystate = READYSTATE_COMPLETE;
|
||||
if(!(flags & BINDING_FROMHIST))
|
||||
call_docview_84(window->doc_obj);
|
||||
|
||||
IUri_AddRef(uri);
|
||||
task->window = window;
|
||||
task->uri = uri;
|
||||
hres = push_task(&task->header, navigate_javascript_proc, navigate_javascript_task_destr, window->task_magic);
|
||||
}
|
||||
|
||||
return hres;
|
||||
|
@ -2396,7 +2402,8 @@ HRESULT hlink_frame_navigate(HTMLDocument *doc, LPCWSTR url, nsChannel *nschanne
|
|||
return hres;
|
||||
}
|
||||
|
||||
static HRESULT navigate_uri(HTMLOuterWindow *window, IUri *uri, const WCHAR *display_uri, DWORD flags)
|
||||
static HRESULT navigate_uri(HTMLOuterWindow *window, IUri *uri, const WCHAR *display_uri, const request_data_t *request_data,
|
||||
DWORD flags)
|
||||
{
|
||||
nsWineURI *nsuri;
|
||||
HRESULT hres;
|
||||
|
@ -2404,18 +2411,22 @@ static HRESULT navigate_uri(HTMLOuterWindow *window, IUri *uri, const WCHAR *dis
|
|||
TRACE("%s\n", debugstr_w(display_uri));
|
||||
|
||||
if(window->doc_obj && window->doc_obj->webbrowser && window == window->doc_obj->basedoc.window) {
|
||||
DWORD post_data_len = request_data ? request_data->post_data_len : 0;
|
||||
void *post_data = post_data_len ? request_data->post_data : NULL;
|
||||
const WCHAR *headers = request_data ? request_data->headers : NULL;
|
||||
|
||||
if(!(flags & BINDING_REFRESH)) {
|
||||
BOOL cancel = FALSE;
|
||||
|
||||
hres = IDocObjectService_FireBeforeNavigate2(window->doc_obj->doc_object_service, NULL, display_uri, 0x40,
|
||||
NULL, NULL, 0, NULL, TRUE, &cancel);
|
||||
NULL, post_data, post_data_len ? post_data_len+1 : 0, headers, TRUE, &cancel);
|
||||
if(SUCCEEDED(hres) && cancel) {
|
||||
TRACE("Navigation canceled\n");
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return super_navigate(window, uri, flags, NULL, NULL, 0);
|
||||
return super_navigate(window, uri, flags, headers, post_data, post_data_len);
|
||||
}
|
||||
|
||||
if(window->doc_obj && window == window->doc_obj->basedoc.window) {
|
||||
|
@ -2449,31 +2460,21 @@ HRESULT load_uri(HTMLOuterWindow *window, IUri *uri, DWORD flags)
|
|||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = navigate_uri(window, uri, display_uri, flags);
|
||||
hres = navigate_uri(window, uri, display_uri, NULL, flags);
|
||||
SysFreeString(display_uri);
|
||||
return hres;
|
||||
}
|
||||
|
||||
HRESULT navigate_url(HTMLOuterWindow *window, const WCHAR *new_url, IUri *base_uri, DWORD flags)
|
||||
static HRESULT translate_uri(HTMLOuterWindow *window, IUri *orig_uri, BSTR *ret_display_uri, IUri **ret_uri)
|
||||
{
|
||||
IUri *uri = NULL;
|
||||
BSTR display_uri;
|
||||
IUri *uri;
|
||||
HRESULT hres;
|
||||
|
||||
if(new_url && base_uri)
|
||||
hres = CoInternetCombineUrlEx(base_uri, new_url, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO,
|
||||
&uri, 0);
|
||||
else
|
||||
hres = create_uri(new_url, 0, &uri);
|
||||
hres = IUri_GetDisplayUri(orig_uri, &display_uri);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = IUri_GetDisplayUri(uri, &display_uri);
|
||||
if(FAILED(hres)) {
|
||||
IUri_Release(uri);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if(window->doc_obj && window->doc_obj->hostui) {
|
||||
OLECHAR *translated_url = NULL;
|
||||
|
||||
|
@ -2482,7 +2483,6 @@ HRESULT navigate_url(HTMLOuterWindow *window, const WCHAR *new_url, IUri *base_u
|
|||
if(hres == S_OK) {
|
||||
TRACE("%08x %s -> %s\n", hres, debugstr_w(display_uri), debugstr_w(translated_url));
|
||||
SysFreeString(display_uri);
|
||||
IUri_Release(uri);
|
||||
hres = create_uri(translated_url, 0, &uri);
|
||||
CoTaskMemFree(translated_url);
|
||||
if(FAILED(hres))
|
||||
|
@ -2496,8 +2496,57 @@ HRESULT navigate_url(HTMLOuterWindow *window, const WCHAR *new_url, IUri *base_u
|
|||
}
|
||||
}
|
||||
|
||||
hres = navigate_uri(window, uri, display_uri, flags);
|
||||
if(!uri) {
|
||||
IUri_AddRef(orig_uri);
|
||||
uri = orig_uri;
|
||||
}
|
||||
|
||||
*ret_display_uri = display_uri;
|
||||
*ret_uri = uri;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT submit_form(HTMLOuterWindow *window, IUri *submit_uri, nsIInputStream *post_stream)
|
||||
{
|
||||
request_data_t request_data = {NULL};
|
||||
BSTR display_uri;
|
||||
IUri *uri;
|
||||
HRESULT hres;
|
||||
|
||||
hres = read_post_data_stream(post_stream, TRUE, NULL, &request_data);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = translate_uri(window, submit_uri, &display_uri, &uri);
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = navigate_uri(window, uri, display_uri, &request_data, BINDING_NAVIGATED|BINDING_SUBMIT);
|
||||
IUri_Release(uri);
|
||||
SysFreeString(display_uri);
|
||||
}
|
||||
release_request_data(&request_data);
|
||||
return hres;
|
||||
}
|
||||
|
||||
HRESULT navigate_url(HTMLOuterWindow *window, const WCHAR *new_url, IUri *base_uri, DWORD flags)
|
||||
{
|
||||
IUri *uri, *nav_uri;
|
||||
BSTR display_uri;
|
||||
HRESULT hres;
|
||||
|
||||
if(new_url && base_uri)
|
||||
hres = CoInternetCombineUrlEx(base_uri, new_url, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO,
|
||||
&nav_uri, 0);
|
||||
else
|
||||
hres = create_uri(new_url, 0, &nav_uri);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = translate_uri(window, nav_uri, &display_uri, &uri);
|
||||
IUri_Release(nav_uri);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
hres = navigate_uri(window, uri, display_uri, NULL, flags);
|
||||
IUri_Release(uri);
|
||||
SysFreeString(display_uri);
|
||||
return hres;
|
||||
|
|
|
@ -438,9 +438,9 @@ HRESULT set_moniker(HTMLOuterWindow *window, IMoniker *mon, IUri *nav_uri, IBind
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
void set_ready_state(HTMLOuterWindow *window, READYSTATE readystate)
|
||||
static void notif_readystate(HTMLOuterWindow *window)
|
||||
{
|
||||
window->readystate = readystate;
|
||||
window->readystate_pending = FALSE;
|
||||
|
||||
if(window->doc_obj && window->doc_obj->basedoc.window == window)
|
||||
call_property_onchanged(&window->doc_obj->basedoc.cp_container, DISPID_READYSTATE);
|
||||
|
@ -453,6 +453,52 @@ void set_ready_state(HTMLOuterWindow *window, READYSTATE readystate)
|
|||
TRUE, window->frame_element->element.node.nsnode, NULL, NULL);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
task_t header;
|
||||
HTMLOuterWindow *window;
|
||||
} readystate_task_t;
|
||||
|
||||
static void notif_readystate_proc(task_t *_task)
|
||||
{
|
||||
readystate_task_t *task = (readystate_task_t*)_task;
|
||||
notif_readystate(task->window);
|
||||
}
|
||||
|
||||
static void notif_readystate_destr(task_t *_task)
|
||||
{
|
||||
readystate_task_t *task = (readystate_task_t*)_task;
|
||||
IHTMLWindow2_Release(&task->window->base.IHTMLWindow2_iface);
|
||||
}
|
||||
|
||||
void set_ready_state(HTMLOuterWindow *window, READYSTATE readystate)
|
||||
{
|
||||
READYSTATE prev_state = window->readystate;
|
||||
|
||||
window->readystate = readystate;
|
||||
|
||||
if(window->readystate_locked) {
|
||||
readystate_task_t *task;
|
||||
HRESULT hres;
|
||||
|
||||
if(window->readystate_pending || prev_state == readystate)
|
||||
return;
|
||||
|
||||
task = heap_alloc(sizeof(*task));
|
||||
if(!task)
|
||||
return;
|
||||
|
||||
IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
|
||||
task->window = window;
|
||||
|
||||
hres = push_task(&task->header, notif_readystate_proc, notif_readystate_destr, window->task_magic);
|
||||
if(SUCCEEDED(hres))
|
||||
window->readystate_pending = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
notif_readystate(window);
|
||||
}
|
||||
|
||||
static HRESULT get_doc_string(HTMLDocumentNode *This, char **str)
|
||||
{
|
||||
nsIDOMNode *nsnode;
|
||||
|
|
Loading…
Reference in New Issue