diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c
index 89dbb266c64..50e5b997d55 100644
--- a/dlls/mshtml/htmldoc.c
+++ b/dlls/mshtml/htmldoc.c
@@ -999,7 +999,7 @@ HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject)
HTMLDocument_Service_Init(ret);
HTMLDocument_Hlink_Init(ret);
- NSContainer_Create(ret);
+ ret->nscontainer = NSContainer_Create(ret, NULL);
return hres;
}
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 478c91dd0f1..ab89c9be70e 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -94,6 +94,7 @@ struct NSContainer {
LONG ref;
+ NSContainer *parent;
HTMLDocument *doc;
HWND hwnd;
@@ -140,7 +141,7 @@ void HTMLDocument_Window_Init(HTMLDocument*);
void HTMLDocument_Service_Init(HTMLDocument*);
void HTMLDocument_Hlink_Init(HTMLDocument*);
-void NSContainer_Create(HTMLDocument *doc);
+NSContainer *NSContainer_Create(HTMLDocument*,NSContainer*);
void NSContainer_Release(NSContainer*);
void HTMLDocument_LockContainer(HTMLDocument*,BOOL);
@@ -149,10 +150,10 @@ void HTMLDocument_ShowContextMenu(HTMLDocument*,DWORD,POINT*);
HRESULT ProtocolFactory_Create(REFCLSID,REFIID,void**);
void close_gecko(void);
-void register_nsservice(nsIComponentRegistrar*);
+void register_nsservice(nsIComponentRegistrar*,nsIServiceManager*);
void init_nsio(nsIComponentManager*,nsIComponentRegistrar*);
-void hlink_frame_navigate(NSContainer*,IHlinkFrame*,LPCWSTR,nsIInputStream*);
+void hlink_frame_navigate(HTMLDocument*,IHlinkFrame*,LPCWSTR,nsIInputStream*,DWORD);
nsIURI *get_nsIURI(LPCWSTR);
diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c
index eb64656e3ad..563a5f351fb 100644
--- a/dlls/mshtml/navigate.c
+++ b/dlls/mshtml/navigate.c
@@ -463,8 +463,8 @@ static void parse_post_data(nsIInputStream *post_data_stream, LPWSTR *headers_re
*post_data_len_ret = post_data_len;
}
-void hlink_frame_navigate(NSContainer *container, IHlinkFrame *hlink_frame,
- LPCWSTR uri, nsIInputStream *post_data_stream)
+void hlink_frame_navigate(HTMLDocument *doc, IHlinkFrame *hlink_frame,
+ LPCWSTR uri, nsIInputStream *post_data_stream, DWORD hlnf)
{
IBindStatusCallback *callback;
IBindCtx *bindctx;
@@ -480,7 +480,7 @@ void hlink_frame_navigate(NSContainer *container, IHlinkFrame *hlink_frame,
debugstr_an(post_data, post_data_len));
}
- callback = BSCallback_Create(container->doc, uri, post_data, post_data_len, headers);
+ callback = BSCallback_Create(doc, uri, post_data, post_data_len, headers);
CreateAsyncBindCtx(0, callback, NULL, &bindctx);
hlink = Hlink_Create();
@@ -488,7 +488,12 @@ void hlink_frame_navigate(NSContainer *container, IHlinkFrame *hlink_frame,
CreateURLMoniker(NULL, uri, &mon);
IHlink_SetMonikerReference(hlink, 0, mon, NULL);
- IHlinkFrame_Navigate(hlink_frame, 0, bindctx, callback, hlink);
+ if(hlnf & HLNF_OPENINNEWWINDOW) {
+ static const WCHAR wszBlank[] = {'_','b','l','a','n','k',0};
+ IHlink_SetTargetFrameName(hlink, wszBlank); /* FIXME */
+ }
+
+ IHlinkFrame_Navigate(hlink_frame, hlnf, bindctx, callback, hlink);
IBindCtx_Release(bindctx);
IBindStatusCallback_Release(callback);
diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c
index 3747ba62a62..029fa1ca043 100644
--- a/dlls/mshtml/nsembed.c
+++ b/dlls/mshtml/nsembed.c
@@ -106,6 +106,7 @@ static LRESULT WINAPI nsembed_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
+
static void register_nscontainer_class(void)
{
static WNDCLASSEXW wndclass = {
@@ -358,7 +359,7 @@ static BOOL load_gecko(void)
set_profile();
if(registrar) {
- register_nsservice(registrar);
+ register_nsservice(registrar, pServMgr);
nsIComponentRegistrar_Release(registrar);
}
@@ -487,8 +488,11 @@ static nsrefcnt NSAPI nsWebBrowserChrome_Release(nsIWebBrowserChrome *iface)
TRACE("(%p) ref=%ld\n", This, ref);
- if(!ref)
+ if(!ref) {
+ if(This->parent)
+ nsIWebBrowserChrome_Release(NSWBCHROME(This->parent));
HeapFree(GetProcessHeap(), 0, This);
+ }
return ref;
}
@@ -945,8 +949,8 @@ static nsresult NSAPI nsInterfaceRequestor_GetInterface(nsIInterfaceRequestor *i
NSContainer *This = NSIFACEREQ_THIS(iface);
if(IsEqualGUID(&IID_nsIDOMWindow, riid)) {
- FIXME("(%p)->(IID_nsIDOMWindow %p)\n", This, result);
- return NS_NOINTERFACE;
+ TRACE("(%p)->(IID_nsIDOMWindow %p)\n", This, result);
+ return nsIWebBrowser_GetContentDOMWindow(This->webbrowser, (nsIDOMWindow**)result);
}
return nsIWebBrowserChrome_QueryInterface(NSWBCHROME(This), riid, result);
@@ -961,14 +965,14 @@ static const nsIInterfaceRequestorVtbl nsInterfaceRequestorVtbl = {
nsInterfaceRequestor_GetInterface
};
-void NSContainer_Create(HTMLDocument *doc)
+NSContainer *NSContainer_Create(HTMLDocument *doc, NSContainer *parent)
{
nsIWebBrowserSetup *wbsetup;
NSContainer *ret;
nsresult nsres;
if(!load_gecko())
- return;
+ return NULL;
ret = HeapAlloc(GetProcessHeap(), 0, sizeof(NSContainer));
@@ -982,7 +986,9 @@ void NSContainer_Create(HTMLDocument *doc)
ret->ref = 1;
ret->load_call = FALSE;
- doc->nscontainer = ret;
+ if(parent)
+ nsIWebBrowserChrome_AddRef(NSWBCHROME(parent));
+ ret->parent = parent;
nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, NS_WEBBROWSER_CONTRACTID,
NULL, &IID_nsIWebBrowser, (void**)&ret->webbrowser);
@@ -1050,6 +1056,8 @@ void NSContainer_Create(HTMLDocument *doc)
nsres = nsIWebBrowser_SetParentURIContentListener(ret->webbrowser, NSURICL(ret));
if(NS_FAILED(nsres))
ERR("SetParentURIContentListener failed: %08lx\n", nsres);
+
+ return ret;
}
void NSContainer_Release(NSContainer *This)
diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl
index 6c483aa1f52..83db2f4ee50 100644
--- a/dlls/mshtml/nsiface.idl
+++ b/dlls/mshtml/nsiface.idl
@@ -83,6 +83,8 @@ typedef nsISupports nsIRequestObserver;
typedef nsISupports nsIDOMBarProp;
typedef nsISupports nsIDOMWindowCollection;
typedef nsISupports nsISelection;
+typedef nsISupports nsIPrompt;
+typedef nsISupports nsIAuthPrompt;
[
object,
@@ -703,6 +705,48 @@ interface nsIProfile : nsISupports
nsresult CloneProfile(const PRUnichar *profileName);
}
+[
+ object,
+ uuid(30465632-a777-44cc-90f9-8145475ef999)
+]
+interface nsIWindowCreator : nsISupports
+{
+ nsresult CreateChromeWindow(nsIWebBrowserChrome *parent, PRUint32 chromeFlags,
+ nsIWebBrowserChrome **_retval);
+}
+
+[
+ object,
+ uuid(f673ec81-a4b0-11d6-964b-eb5a2bf216fc)
+]
+interface nsIWindowCreator2 : nsIWindowCreator
+{
+ nsresult CreateChromeWindow2(nsIWebBrowserChrome *parent, PRUint32 chromeFlags,
+ PRUint32 contextFlags, nsIURI *uri, PRBool *cancel,
+ nsIWebBrowserChrome **_retval);
+}
+
+[
+ object,
+ uuid(002286a8-494b-43b3-8ddd-49e3fc50622b)
+]
+interface nsIWindowWatcher : nsISupports
+{
+ nsresult OpenWindow(nsIDOMWindow *aParent, const char *aUrl, const char *aName,
+ const char *aFeatures, nsISupports *aArguments, nsIDOMWindow **_retval);
+ nsresult RegisterNotification(nsIObserver *aObserver);
+ nsresult UnregisterNotification(nsIObserver *aObserver);
+ nsresult GetWindowEnumerator(nsISimpleEnumerator **_retval);
+ nsresult GetNewPrompter(nsIDOMWindow *aParent, nsIPrompt **_retval);
+ nsresult GetNewAuthPrompter(nsIDOMWindow *aParent, nsIAuthPrompt **_retval);
+ nsresult SetWindowCreator(nsIWindowCreator *creator);
+ nsresult GetChromeForWindow(nsIDOMWindow *aWindow, nsIWebBrowserChrome **_retval);
+ nsresult GetWindowByName(const PRUnichar *aTargetName, nsIDOMWindow *aCurrentWindow,
+ nsIDOMWindow **_retval);
+ nsresult GetActiveWindow(nsIDOMWindow **aActiveWindow);
+ nsresult SetActiveWindow(nsIDOMWindow *aActiveWindow);
+}
+
/*
* NOTE:
* This is a private Wine interface that is implemented by our implementation
diff --git a/dlls/mshtml/nsio.c b/dlls/mshtml/nsio.c
index 819d3f8ebd4..9a42cf6b8b5 100644
--- a/dlls/mshtml/nsio.c
+++ b/dlls/mshtml/nsio.c
@@ -77,12 +77,12 @@ typedef struct {
static nsresult create_uri(nsIURI*,NSContainer*,nsIURI**);
-static BOOL exec_shldocvw_67(NSContainer *container, LPCWSTR url)
+static BOOL exec_shldocvw_67(HTMLDocument *doc, LPCWSTR url)
{
IOleCommandTarget *cmdtrg = NULL;
HRESULT hres;
- hres = IOleClientSite_QueryInterface(container->doc->client, &IID_IOleCommandTarget,
+ hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget,
(void**)&cmdtrg);
if(SUCCEEDED(hres)) {
VARIANT varUrl, varRes;
@@ -108,12 +108,23 @@ static BOOL exec_shldocvw_67(NSContainer *container, LPCWSTR url)
static BOOL handle_uri(NSContainer *container, nsChannel *channel, LPCWSTR uri)
{
IServiceProvider *service_provider;
+ HTMLDocument *doc = container->doc;
+ DWORD hlnf = 0;
HRESULT hres;
- if(!exec_shldocvw_67(container, uri))
+ if(!doc) {
+ NSContainer *container_iter = container;
+
+ hlnf = HLNF_OPENINNEWWINDOW;
+ while(!container_iter->doc)
+ container_iter = container_iter->parent;
+ doc = container_iter->doc;
+ }
+
+ if(!hlnf && !exec_shldocvw_67(doc, uri))
return FALSE;
- hres = IOleClientSite_QueryInterface(container->doc->client, &IID_IServiceProvider,
+ hres = IOleClientSite_QueryInterface(doc->client, &IID_IServiceProvider,
(void**)&service_provider);
if(SUCCEEDED(hres)) {
IHlinkFrame *hlink_frame;
@@ -121,7 +132,7 @@ static BOOL handle_uri(NSContainer *container, nsChannel *channel, LPCWSTR uri)
hres = IServiceProvider_QueryService(service_provider, &IID_IHlinkFrame,
&IID_IHlinkFrame, (void**)&hlink_frame);
if(SUCCEEDED(hres)) {
- hlink_frame_navigate(container, hlink_frame, uri, channel->post_data_stream);
+ hlink_frame_navigate(doc, hlink_frame, uri, channel->post_data_stream, hlnf);
IHlinkFrame_Release(hlink_frame);
return FALSE;
diff --git a/dlls/mshtml/nsservice.c b/dlls/mshtml/nsservice.c
index faa69ce6771..62e5a27d54e 100644
--- a/dlls/mshtml/nsservice.c
+++ b/dlls/mshtml/nsservice.c
@@ -36,10 +36,78 @@
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
#define NS_PROMPTSERVICE_CONTRACTID "@mozilla.org/embedcomp/prompt-service;1"
+#define NS_WINDOWWATCHER_CONTRACTID "@mozilla.org/embedcomp/window-watcher;1"
static const nsIID NS_PROMPTSERVICE_CID =
{0xa2112d6a,0x0e28,0x421f,{0xb4,0x6a,0x25,0xc0,0xb3,0x8,0xcb,0xd0}};
+static nsresult NSAPI nsWindowCreator_QueryInterface(nsIWindowCreator2 *iface, nsIIDRef riid,
+ nsQIResult result)
+{
+ *result = NULL;
+
+ if(IsEqualGUID(&IID_nsISupports, riid)) {
+ TRACE("(IID_nsISupports %p)\n", result);
+ *result = iface;
+ }else if(IsEqualGUID(&IID_nsIWindowCreator, riid)) {
+ TRACE("(IID_nsIWindowCreator %p)\n", result);
+ *result = iface;
+ }else if(IsEqualGUID(&IID_nsIWindowCreator2, riid)) {
+ TRACE("(IID_nsIWindowCreator2 %p)\n", result);
+ *result = iface;
+ }
+
+ if(*result) {
+ nsIWindowCreator_AddRef(iface);
+ return NS_OK;
+ }
+
+ WARN("(%s %p)\n", debugstr_guid(riid), result);
+ return NS_NOINTERFACE;
+}
+
+static nsrefcnt NSAPI nsWindowCreator_AddRef(nsIWindowCreator2 *iface)
+{
+ return 2;
+}
+
+static nsrefcnt NSAPI nsWindowCreator_Release(nsIWindowCreator2 *iface)
+{
+ return 1;
+}
+
+static nsresult NSAPI nsWindowCreator_CreateChromeWindow(nsIWindowCreator2 *iface,
+ nsIWebBrowserChrome *parent, PRUint32 chromeFlags, nsIWebBrowserChrome **_retval)
+{
+ TRACE("(%p %08lx %p)\n", parent, chromeFlags, _retval);
+ return nsIWindowCreator2_CreateChromeWindow2(iface, parent, chromeFlags, 0, NULL,
+ NULL, _retval);
+}
+
+static nsresult NSAPI nsWindowCreator_CreateChromeWindow2(nsIWindowCreator2 *iface,
+ nsIWebBrowserChrome *parent, PRUint32 chromeFlags, PRUint32 contextFlags,
+ nsIURI *uri, PRBool *cancel, nsIWebBrowserChrome **_retval)
+{
+ TRACE("(%p %08lx %08lx %p %p %p)\n", parent, chromeFlags, contextFlags, uri,
+ cancel, _retval);
+
+ if(cancel)
+ *cancel = FALSE;
+
+ *_retval = NSWBCHROME(NSContainer_Create(NULL, (NSContainer*)parent));
+ return NS_OK;
+}
+
+static const nsIWindowCreator2Vtbl nsWindowCreatorVtbl = {
+ nsWindowCreator_QueryInterface,
+ nsWindowCreator_AddRef,
+ nsWindowCreator_Release,
+ nsWindowCreator_CreateChromeWindow,
+ nsWindowCreator_CreateChromeWindow2
+};
+
+static nsIWindowCreator2 nsWindowCreator = { &nsWindowCreatorVtbl };
+
static nsresult NSAPI nsPromptService_QueryInterface(nsIPromptService *iface,
nsIIDRef riid, nsQIResult result)
{
@@ -260,17 +328,30 @@ static const nsIFactoryVtbl nsServiceFactoryVtbl = {
nsServiceFactory_LockFactory
};
-static nsServiceFactory PromptServiceFactory = {
+static nsServiceFactory nsPromptServiceFactory = {
&nsServiceFactoryVtbl,
(nsISupports*)&nsPromptService
};
-void register_nsservice(nsIComponentRegistrar *registrar)
+void register_nsservice(nsIComponentRegistrar *registrar, nsIServiceManager *service_manager)
{
+ nsIWindowWatcher *window_watcher;
nsresult nsres;
nsres = nsIComponentRegistrar_RegisterFactory(registrar, &NS_PROMPTSERVICE_CID,
- "Prompt Service", NS_PROMPTSERVICE_CONTRACTID, NSFACTORY(&PromptServiceFactory));
+ "Prompt Service", NS_PROMPTSERVICE_CONTRACTID, NSFACTORY(&nsPromptServiceFactory));
if(NS_FAILED(nsres))
ERR("RegisterFactory failed: %08lx\n", nsres);
+
+ nsres = nsIServiceManager_GetServiceByContactID(service_manager, NS_WINDOWWATCHER_CONTRACTID,
+ &IID_nsIWindowWatcher, (void**)&window_watcher);
+ if(NS_SUCCEEDED(nsres)) {
+ nsres = nsIWindowWatcher_SetWindowCreator(window_watcher,
+ (nsIWindowCreator*)&nsWindowCreator);
+ if(NS_FAILED(nsres))
+ ERR("SetWindowCreator failed: %08lx\n", nsres);
+ nsIWindowWatcher_Release(window_watcher);
+ }else {
+ ERR("Could not get WindowWatcher object: %08lx\n", nsres);
+ }
}