From d656f996f118667a9a455c08a950d4f4ab647a0b Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Wed, 1 Mar 2006 22:04:51 +0100 Subject: [PATCH] mshtml: Beginning support for links opened in a new frame. --- dlls/mshtml/htmldoc.c | 2 +- dlls/mshtml/mshtml_private.h | 7 +-- dlls/mshtml/navigate.c | 13 ++++-- dlls/mshtml/nsembed.c | 22 ++++++--- dlls/mshtml/nsiface.idl | 44 ++++++++++++++++++ dlls/mshtml/nsio.c | 21 ++++++--- dlls/mshtml/nsservice.c | 87 ++++++++++++++++++++++++++++++++++-- 7 files changed, 173 insertions(+), 23 deletions(-) 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); + } }