nsIURI *uri;
nsIURL *nsurl;
NSContainer *container;
+ windowref_t *window_ref;
LPWSTR wine_url;
PRBool is_doc_uri;
BOOL use_wine_url;
#define NSURI(x) ((nsIURI*) &(x)->lpWineURIVtbl)
#define NSWINEURI(x) ((nsIWineURI*) &(x)->lpWineURIVtbl)
-static nsresult create_uri(nsIURI*,NSContainer*,nsIWineURI**);
+static nsresult create_uri(nsIURI*,HTMLWindow*,NSContainer*,nsIWineURI**);
static const char *debugstr_nsacstr(const nsACString *nsstr)
{
static BOOL before_async_open(nsChannel *channel, NSContainer *container)
{
HTMLDocumentObj *doc = container->doc;
- IServiceProvider *service_provider;
DWORD hlnf = 0;
LPCWSTR uri;
HRESULT hres;
if(!hlnf && !exec_shldocvw_67(doc, uri))
return FALSE;
- hres = IOleClientSite_QueryInterface(doc->client, &IID_IServiceProvider,
- (void**)&service_provider);
- if(SUCCEEDED(hres)) {
- IHlinkFrame *hlink_frame;
-
- hres = IServiceProvider_QueryService(service_provider, &IID_IHlinkFrame,
- &IID_IHlinkFrame, (void**)&hlink_frame);
- IServiceProvider_Release(service_provider);
- if(SUCCEEDED(hres)) {
- hlink_frame_navigate(&doc->basedoc, hlink_frame, uri, channel->post_data_stream, hlnf);
- IHlinkFrame_Release(hlink_frame);
-
- return FALSE;
+ hres = hlink_frame_navigate(&doc->basedoc, uri, channel->post_data_stream, hlnf);
+ return hres != S_OK;
}
- }
-
- return TRUE;
-}
#define NSCHANNEL_THIS(iface) DEFINE_THIS(nsChannel, HttpChannel, iface)
if(This->channel)
return nsIChannel_GetContentType(This->channel, aContentType);
- TRACE("returning default text/html\n");
- nsACString_SetData(aContentType, "text/html");
- return NS_OK;
+ WARN("unknown type\n");
+ return NS_ERROR_FAILURE;
}
static nsresult NSAPI nsChannel_SetContentType(nsIHttpChannel *iface,
hres = CreateURLMoniker(NULL, wine_url, mon);
if(FAILED(hres))
- WARN("CreateURLMonikrer failed: %08x\n", hres);
+ WARN("CreateURLMoniker failed: %08x\n", hres);
return hres;
}
-static NSContainer *get_nscontainer_from_load_group(nsChannel *This)
+static HTMLWindow *get_window_from_load_group(nsChannel *This)
{
- NSContainer *container;
+ HTMLWindow *window;
nsIChannel *channel;
nsIRequest *req;
nsIWineURI *wine_uri;
return NULL;
}
- nsIWineURI_GetNSContainer(wine_uri, &container);
+ nsIWineURI_GetWindow(wine_uri, &window);
nsIWineURI_Release(wine_uri);
- return container;
+ return window;
}
-static nsresult async_open_doc_uri(nsChannel *This, NSContainer *container,
- nsIStreamListener *listener, nsISupports *context, BOOL *open)
+static HTMLWindow *get_channel_window(nsChannel *This)
{
- IMoniker *mon;
- HRESULT hres;
+ nsIRequestObserver *req_observer;
+ nsIWebProgress *web_progress;
+ nsIDOMWindow *nswindow;
+ HTMLWindow *window;
+ nsresult nsres;
- *open = FALSE;
+ if(!This->load_group) {
+ ERR("NULL load_group\n");
+ return NULL;
+ }
- if(container->bscallback) {
- channelbsc_set_channel(container->bscallback, This, listener, context);
+ nsres = nsILoadGroup_GetGroupObserver(This->load_group, &req_observer);
+ if(NS_FAILED(nsres) || !req_observer) {
+ ERR("GetGroupObserver failed: %08x\n", nsres);
+ return NULL;
+ }
- if(container->doc && container->doc->mime) {
- heap_free(This->content_type);
- This->content_type = heap_strdupWtoA(container->doc->mime);
+ nsres = nsIRequestObserver_QueryInterface(req_observer, &IID_nsIWebProgress, (void**)&web_progress);
+ nsIRequestObserver_Release(req_observer);
+ if(NS_FAILED(nsres)) {
+ ERR("Could not get nsIWebProgress iface: %08x\n", nsres);
+ return NULL;
}
- return NS_OK;
- }else {
- BOOL cont = before_async_open(This, container);
-
- if(!cont) {
- TRACE("canceled\n");
- return NS_ERROR_UNEXPECTED;
+ nsres = nsIWebProgress_GetDOMWindow(web_progress, &nswindow);
+ nsIWebProgress_Release(web_progress);
+ if(NS_FAILED(nsres) || !nswindow) {
+ ERR("GetDOMWindow failed: %08x\n", nsres);
+ return NULL;
}
- if(!container->doc) {
- return This->channel
- ? nsIChannel_AsyncOpen(This->channel, listener, context)
- : NS_ERROR_UNEXPECTED;
+ window = nswindow_to_window(nswindow);
+ nsIDOMWindow_Release(nswindow);
+
+ if(window)
+ IHTMLWindow2_AddRef(HTMLWINDOW2(window));
+ else
+ FIXME("NULL window for %p\n", nswindow);
+ return window;
}
- hres = create_mon_for_nschannel(This, &mon);
- if(FAILED(hres)) {
- return NS_ERROR_UNEXPECTED;
+typedef struct {
+ task_t header;
+ HTMLDocumentNode *doc;
+ nsChannelBSC *bscallback;
+} start_binding_task_t;
+
+static void start_binding_proc(task_t *_task)
+{
+ start_binding_task_t *task = (start_binding_task_t*)_task;
+
+ start_binding(NULL, task->doc, (BSCallback*)task->bscallback, NULL);
}
- set_current_mon(&container->doc->basedoc, mon);
- }
- *open = TRUE;
- return NS_OK;
+typedef struct {
+ task_t header;
+ HTMLWindow *window;
+ nsChannelBSC *bscallback;
+} start_doc_binding_task_t;
+
+static void start_doc_binding_proc(task_t *_task)
+{
+ start_doc_binding_task_t *task = (start_doc_binding_task_t*)_task;
+
+ start_binding(task->window, NULL, (BSCallback*)task->bscallback, NULL);
+ IUnknown_Release((IUnknown*)task->bscallback);
}
-static nsresult async_open(nsChannel *This, NSContainer *container, nsIStreamListener *listener,
+static nsresult async_open(nsChannel *This, HTMLWindow *window, BOOL is_doc_channel, nsIStreamListener *listener,
nsISupports *context)
{
nsChannelBSC *bscallback;
IMoniker *mon = NULL;
- task_t *task;
HRESULT hres;
hres = create_mon_for_nschannel(This, &mon);
if(FAILED(hres))
return NS_ERROR_UNEXPECTED;
+ if(is_doc_channel)
+ set_current_mon(window, mon);
+
bscallback = create_channelbsc(mon);
IMoniker_Release(mon);
channelbsc_set_channel(bscallback, This, listener, context);
- task = heap_alloc(sizeof(task_t));
+ if(is_doc_channel) {
+ start_doc_binding_task_t *task;
- task->doc = &container->doc->basedoc;
- task->task_id = TASK_START_BINDING;
- task->next = NULL;
+ set_window_bscallback(window, bscallback);
+
+ task = heap_alloc(sizeof(start_doc_binding_task_t));
+ task->window = window;
task->bscallback = bscallback;
+ push_task(&task->header, start_doc_binding_proc, window->task_magic);
+ }else {
+ start_binding_task_t *task = heap_alloc(sizeof(start_binding_task_t));
- push_task(task);
+ task->doc = window->doc;
+ task->bscallback = bscallback;
+ push_task(&task->header, start_binding_proc, window->doc->basedoc.task_magic);
+ }
return NS_OK;
}
nsISupports *aContext)
{
nsChannel *This = NSCHANNEL_THIS(iface);
- NSContainer *container;
+ HTMLWindow *window = NULL;
PRBool is_doc_uri;
BOOL open = TRUE;
nsresult nsres = NS_OK;
TRACE("(%p)->(%p %p)\n", This, aListener, aContext);
- nsIWineURI_GetNSContainer(This->uri, &container);
+ if(TRACE_ON(mshtml)) {
+ LPCWSTR url;
- if(!container && This->load_group) {
- container = get_nscontainer_from_load_group(This);
- if(container)
- nsIWineURI_SetNSContainer(This->uri, container);
+ nsIWineURI_GetWineURL(This->uri, &url);
+ TRACE("opening %s\n", debugstr_w(url));
}
- if(!container) {
- TRACE("container = NULL\n");
+ nsIWineURI_GetIsDocumentURI(This->uri, &is_doc_uri);
+ if(is_doc_uri) {
+ window = get_channel_window(This);
+ if(window) {
+ nsIWineURI_SetWindow(This->uri, window);
+ }else {
+ NSContainer *nscontainer;
+
+ nsIWineURI_GetNSContainer(This->uri, &nscontainer);
+ if(nscontainer) {
+ BOOL b;
+
+ /* nscontainer->doc should be NULL which means navigation to a new window */
+ if(nscontainer->doc)
+ FIXME("nscontainer->doc = %p\n", nscontainer->doc);
+
+ b = before_async_open(This, nscontainer);
+ nsIWebBrowserChrome_Release(NSWBCHROME(nscontainer));
+ if(b)
+ FIXME("Navigation not cancelled\n");
+ return NS_ERROR_UNEXPECTED;
+ }
+ }
+ }
+
+ if(!window) {
+ nsIWineURI_GetWindow(This->uri, &window);
+
+ if(!window && This->load_group) {
+ window = get_window_from_load_group(This);
+ if(window)
+ nsIWineURI_SetWindow(This->uri, window);
+ }
+ }
+
+ if(!window) {
+ TRACE("window = NULL\n");
return This->channel
? nsIChannel_AsyncOpen(This->channel, aListener, aContext)
: NS_ERROR_UNEXPECTED;
}
- nsIWineURI_GetIsDocumentURI(This->uri, &is_doc_uri);
+ if(is_doc_uri && (This->load_flags & LOAD_INITIAL_DOCUMENT_URI)) {
+ if(window->doc_obj->nscontainer->bscallback) {
+ NSContainer *nscontainer = window->doc_obj->nscontainer;
+
+ channelbsc_set_channel(nscontainer->bscallback, This, aListener, aContext);
- if(is_doc_uri && (This->load_flags & LOAD_INITIAL_DOCUMENT_URI))
- nsres = async_open_doc_uri(This, container, aListener, aContext, &open);
+ if(nscontainer->doc->mime) {
+ heap_free(This->content_type);
+ This->content_type = heap_strdupWtoA(nscontainer->doc->mime);
+ }
+
+ open = FALSE;
+ }else {
+ open = before_async_open(This, window->doc_obj->nscontainer);
+ if(!open) {
+ TRACE("canceled\n");
+ nsres = NS_ERROR_UNEXPECTED;
+ }
+ }
+ }
if(open)
- nsres = async_open(This, container, aListener, aContext);
+ nsres = async_open(This, window, is_doc_uri, aListener, aContext);
- nsIWebBrowserChrome_Release(NSWBCHROME(container));
+ if(window)
+ IHTMLWindow2_Release(HTMLWINDOW2(window));
return nsres;
}
TRACE("(%p) ref=%d\n", This, ref);
if(!ref) {
+ if(This->window_ref)
+ windowref_release(This->window_ref);
if(This->container)
nsIWebBrowserChrome_Release(NSWBCHROME(This->container));
if(This->nsurl)
}
nsIWineURI_GetWineURL(wine_uri, &other_url);
- *_retval = !UrlCompareW(This->wine_url, other_url, TRUE);
+ *_retval = other_url && !UrlCompareW(This->wine_url, other_url, TRUE);
nsIWineURI_Release(wine_uri);
return NS_OK;
}
}
- nsres = create_uri(nsuri, This->container, &wine_uri);
+ nsres = create_uri(nsuri, This->window_ref ? This->window_ref->window : NULL, This->container, &wine_uri);
if(NS_FAILED(nsres)) {
WARN("create_uri failed: %08x\n", nsres);
return nsres;
static nsresult NSAPI nsURL_SetRef(nsIWineURI *iface, const nsACString *aRef)
{
nsURI *This = NSURI_THIS(iface);
+ const char *refa;
TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRef));
if(This->nsurl)
return nsIURL_SetRef(This->nsurl, aRef);
+ nsACString_GetData(aRef, &refa);
+ if(!*refa)
+ return NS_OK;
+
FIXME("default action not implemented\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
return NS_OK;
}
+static nsresult NSAPI nsURI_GetWindow(nsIWineURI *iface, HTMLWindow **aHTMLWindow)
+{
+ nsURI *This = NSURI_THIS(iface);
+
+ TRACE("(%p)->(%p)\n", This, aHTMLWindow);
+
+ if(This->window_ref && This->window_ref->window) {
+ IHTMLWindow2_AddRef(HTMLWINDOW2(This->window_ref->window));
+ *aHTMLWindow = This->window_ref->window;
+ }else {
+ *aHTMLWindow = NULL;
+ }
+
+ return NS_OK;
+}
+
+static nsresult NSAPI nsURI_SetWindow(nsIWineURI *iface, HTMLWindow *aHTMLWindow)
+{
+ nsURI *This = NSURI_THIS(iface);
+
+ TRACE("(%p)->(%p)\n", This, aHTMLWindow);
+
+ if(This->window_ref) {
+ if(This->window_ref->window == aHTMLWindow)
+ return NS_OK;
+ TRACE("Changing %p -> %p\n", This->window_ref->window, aHTMLWindow);
+ windowref_release(This->window_ref);
+ }
+
+ if(aHTMLWindow) {
+ windowref_addref(aHTMLWindow->window_ref);
+ This->window_ref = aHTMLWindow->window_ref;
+
+ if(aHTMLWindow->doc_obj)
+ nsIWineURI_SetNSContainer(NSWINEURI(This), aHTMLWindow->doc_obj->nscontainer);
+ }else {
+ This->window_ref = NULL;
+ }
+
+ return NS_OK;
+}
+
static nsresult NSAPI nsURI_GetIsDocumentURI(nsIWineURI *iface, PRBool *aIsDocumentURI)
{
nsURI *This = NSURI_THIS(iface);
nsURL_GetRelativeSpec,
nsURI_GetNSContainer,
nsURI_SetNSContainer,
+ nsURI_GetWindow,
+ nsURI_SetWindow,
nsURI_GetIsDocumentURI,
nsURI_SetIsDocumentURI,
nsURI_GetWineURL,
nsURI_SetWineURL
};
-static nsresult create_uri(nsIURI *uri, NSContainer *container, nsIWineURI **_retval)
+static nsresult create_uri(nsIURI *uri, HTMLWindow *window, NSContainer *container, nsIWineURI **_retval)
{
- nsURI *ret = heap_alloc(sizeof(nsURI));
+ nsURI *ret = heap_alloc_zero(sizeof(nsURI));
ret->lpWineURIVtbl = &nsWineURIVtbl;
ret->ref = 1;
ret->uri = uri;
- ret->container = container;
- ret->wine_url = NULL;
- ret->is_doc_uri = FALSE;
- ret->use_wine_url = FALSE;
- if(container)
- nsIWebBrowserChrome_AddRef(NSWBCHROME(container));
+ nsIWineURI_SetNSContainer(NSWINEURI(ret), container);
+ nsIWineURI_SetWindow(NSWINEURI(ret), window);
if(uri)
nsIURI_QueryInterface(uri, &IID_nsIURL, (void**)&ret->nsurl);
const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
{
const char *spec = NULL;
- NSContainer *nscontainer = NULL;
+ HTMLWindow *window = NULL;
nsIURI *uri = NULL;
LPCWSTR base_wine_url = NULL;
nsIWineURI *base_wine_uri = NULL, *wine_uri;
if(aBaseURI) {
nsres = nsIURI_QueryInterface(aBaseURI, &IID_nsIWineURI, (void**)&base_wine_uri);
if(NS_SUCCEEDED(nsres)) {
- nsIWineURI_GetNSContainer(base_wine_uri, &nscontainer);
+ nsIWineURI_GetWindow(base_wine_uri, &window);
nsIWineURI_GetWineURL(base_wine_uri, &base_wine_url);
}else {
TRACE("Could not get base nsIWineURI: %08x\n", nsres);
}
}
- TRACE("nscontainer = %p\n", nscontainer);
+ TRACE("window = %p\n", window);
- nsres = create_uri(uri, nscontainer, &wine_uri);
+ nsres = create_uri(uri, window, NULL, &wine_uri);
*_retval = (nsIURI*)wine_uri;
- if(nscontainer)
- nsIWebBrowserChrome_Release(NSWBCHROME(nscontainer));
+ if(window)
+ IHTMLWindow2_Release(HTMLWINDOW2(window));
if(base_wine_url) {
WCHAR url[INTERNET_MAX_URL_LENGTH], rel_url[INTERNET_MAX_URL_LENGTH];