diff options
author | stoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-08 16:26:11 +0000 |
---|---|---|
committer | stoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-08 16:26:11 +0000 |
commit | b1c5563861d33febd3ba84dfac70c7b6921bda26 (patch) | |
tree | 8f7f9747e59f42cf0878edb8e599a3151e944045 | |
parent | 57fc471c6864dea93852742643e32d35a30c8559 (diff) | |
download | chromium_src-b1c5563861d33febd3ba84dfac70c7b6921bda26.zip chromium_src-b1c5563861d33febd3ba84dfac70c7b6921bda26.tar.gz chromium_src-b1c5563861d33febd3ba84dfac70c7b6921bda26.tar.bz2 |
ChromeFrame now uses host provided popup blocker.
It does not work in all scenarions since from Chrome side an empty string is passed as target url.
Note in IE6 "Tools/Popup Blocker" menu is not visible if ChromeFrame is the activedocument. Have to support some IOleCommandTarget command..
BUG=34823
Review URL: http://codereview.chromium.org/668168
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40897 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/automation/automation_provider.h | 3 | ||||
-rw-r--r-- | chrome/browser/automation/automation_provider_win.cc | 7 | ||||
-rw-r--r-- | chrome/browser/external_tab_container.cc | 20 | ||||
-rw-r--r-- | chrome/browser/external_tab_container.h | 4 | ||||
-rw-r--r-- | chrome/test/automation/automation_messages.h | 41 | ||||
-rw-r--r-- | chrome/test/automation/automation_messages_internal.h | 12 | ||||
-rw-r--r-- | chrome/test/automation/automation_proxy_uitest.cc | 12 | ||||
-rw-r--r-- | chrome/test/automation/automation_proxy_uitest.h | 11 | ||||
-rw-r--r-- | chrome_frame/chrome_active_document.cc | 35 | ||||
-rw-r--r-- | chrome_frame/chrome_active_document.h | 5 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_activex_base.h | 189 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_automation.cc | 19 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_automation.h | 5 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_delegate.h | 4 | ||||
-rw-r--r-- | chrome_frame/chrome_launcher.cc | 1 |
15 files changed, 226 insertions, 142 deletions
diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h index 02b695e..66b82f7 100644 --- a/chrome/browser/automation/automation_provider.h +++ b/chrome/browser/automation/automation_provider.h @@ -317,7 +317,8 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>, gfx::NativeWindow* tab_window, int* tab_handle); - void ConnectExternalTab(intptr_t cookie, + void ConnectExternalTab(uint64 cookie, + bool allow, gfx::NativeWindow* tab_container_window, gfx::NativeWindow* tab_window, int* tab_handle); diff --git a/chrome/browser/automation/automation_provider_win.cc b/chrome/browser/automation/automation_provider_win.cc index ecdcd57..9539498 100644 --- a/chrome/browser/automation/automation_provider_win.cc +++ b/chrome/browser/automation/automation_provider_win.cc @@ -436,7 +436,8 @@ void AutomationProvider::OnForwardContextMenuCommandToChrome(int tab_handle, } void AutomationProvider::ConnectExternalTab( - intptr_t cookie, + uint64 cookie, + bool allow, gfx::NativeWindow* tab_container_window, gfx::NativeWindow* tab_window, int* tab_handle) { @@ -445,13 +446,13 @@ void AutomationProvider::ConnectExternalTab( *tab_window = NULL; scoped_refptr<ExternalTabContainer> external_tab_container = - ExternalTabContainer::RemovePendingTab(cookie); + ExternalTabContainer::RemovePendingTab(static_cast<uintptr_t>(cookie)); if (!external_tab_container.get()) { NOTREACHED(); return; } - if (AddExternalTab(external_tab_container)) { + if (allow && AddExternalTab(external_tab_container)) { external_tab_container->Reinitialize(this, automation_resource_message_filter_); TabContents* tab_contents = external_tab_container->tab_contents(); diff --git a/chrome/browser/external_tab_container.cc b/chrome/browser/external_tab_container.cc index 842341b..08c9fe7 100644 --- a/chrome/browser/external_tab_container.cc +++ b/chrome/browser/external_tab_container.cc @@ -355,16 +355,16 @@ void ExternalTabContainer::AddNewContents(TabContents* source, GURL()); if (result) { - pending_tabs_[reinterpret_cast<intptr_t>(new_container.get())] = - new_container; - + uintptr_t cookie = reinterpret_cast<uintptr_t>(new_container.get()); + pending_tabs_[cookie] = new_container; new_container->set_pending(true); - - automation_->Send(new AutomationMsg_AttachExternalTab( - 0, - tab_handle_, - reinterpret_cast<intptr_t>(new_container.get()), - disposition)); + IPC::AttachExternalTabParams attach_params_; + attach_params_.cookie = static_cast<uint64>(cookie); + attach_params_.dimensions = initial_pos; + attach_params_.user_gesture = user_gesture; + attach_params_.disposition = disposition; + automation_->Send(new AutomationMsg_AttachExternalTab(0, + tab_handle_, attach_params_)); } else { NOTREACHED(); } @@ -739,7 +739,7 @@ bool ExternalTabContainer::InitNavigationInfo(IPC::NavigationInfo* nav_info, } scoped_refptr<ExternalTabContainer> ExternalTabContainer::RemovePendingTab( - intptr_t cookie) { + uintptr_t cookie) { PendingTabs::iterator index = pending_tabs_.find(cookie); if (index != pending_tabs_.end()) { scoped_refptr<ExternalTabContainer> container = (*index).second; diff --git a/chrome/browser/external_tab_container.h b/chrome/browser/external_tab_container.h index d3d8625..4122b62 100644 --- a/chrome/browser/external_tab_container.h +++ b/chrome/browser/external_tab_container.h @@ -43,7 +43,7 @@ class ExternalTabContainer : public TabContentsDelegate, public InfoBarContainer::Delegate, public BrowserBubbleHost { public: - typedef std::map<intptr_t, scoped_refptr<ExternalTabContainer> > PendingTabs; + typedef std::map<uintptr_t, scoped_refptr<ExternalTabContainer> > PendingTabs; ExternalTabContainer(AutomationProvider* automation, AutomationResourceMessageFilter* filter); @@ -171,7 +171,7 @@ class ExternalTabContainer : public TabContentsDelegate, // Returns the ExternalTabContainer instance associated with the cookie // passed in. It also erases the corresponding reference from the map. // Returns NULL if we fail to find the cookie in the map. - static scoped_refptr<ExternalTabContainer> RemovePendingTab(intptr_t cookie); + static scoped_refptr<ExternalTabContainer> RemovePendingTab(uintptr_t cookie); // Enables extension automation (for e.g. UITests), with the current tab // used as a conduit for the extension API messages being handled by the diff --git a/chrome/test/automation/automation_messages.h b/chrome/test/automation/automation_messages.h index 49014dc..e6911c0 100644 --- a/chrome/test/automation/automation_messages.h +++ b/chrome/test/automation/automation_messages.h @@ -524,6 +524,47 @@ struct ParamTraits<ContextMenuParams> { } }; +struct AttachExternalTabParams { + uint64 cookie; + GURL url; + gfx::Rect dimensions; + int disposition; + bool user_gesture; +}; + +template <> +struct ParamTraits<AttachExternalTabParams> { + typedef AttachExternalTabParams param_type; + static void Write(Message* m, const param_type& p) { + WriteParam(m, p.cookie); + WriteParam(m, p.url); + WriteParam(m, p.dimensions); + WriteParam(m, p.disposition); + WriteParam(m, p.user_gesture); + } + + static bool Read(const Message* m, void** iter, param_type* p) { + return ReadParam(m, iter, &p->cookie) && + ReadParam(m, iter, &p->url) && + ReadParam(m, iter, &p->dimensions) && + ReadParam(m, iter, &p->disposition) && + ReadParam(m, iter, &p->user_gesture); + } + + static void Log(const param_type& p, std::wstring* l) { + l->append(L"("); + LogParam(p.cookie, l); + l->append(L", "); + LogParam(p.url, l); + l->append(L", "); + LogParam(p.dimensions, l); + l->append(L", "); + LogParam(p.disposition, l); + l->append(L", "); + LogParam(p.user_gesture, l); + l->append(L")"); + } +}; } // namespace IPC diff --git a/chrome/test/automation/automation_messages_internal.h b/chrome/test/automation/automation_messages_internal.h index 29bd287..6a18cd3 100644 --- a/chrome/test/automation/automation_messages_internal.h +++ b/chrome/test/automation/automation_messages_internal.h @@ -1091,14 +1091,14 @@ IPC_BEGIN_MESSAGES(Automation) IPC_MESSAGE_ROUTED1(AutomationMsg_RecordHistograms, std::vector<std::string> /* histogram_list */) - IPC_MESSAGE_ROUTED3(AutomationMsg_AttachExternalTab, - int /* tab_handle */, - intptr_t /* cookie */, - int /* disposition */) + IPC_MESSAGE_ROUTED2(AutomationMsg_AttachExternalTab, + int /* 'source' tab_handle */, + IPC::AttachExternalTabParams) // Sent when the automation client connects to an existing tab. - IPC_SYNC_MESSAGE_ROUTED1_3(AutomationMsg_ConnectExternalTab, - intptr_t /* cookie */, + IPC_SYNC_MESSAGE_ROUTED2_3(AutomationMsg_ConnectExternalTab, + uint64 /* cookie */, + bool /* allow/block tab*/, gfx::NativeWindow /* Tab container window */, gfx::NativeWindow /* Tab window */, int /* Handle to the new tab */) diff --git a/chrome/test/automation/automation_proxy_uitest.cc b/chrome/test/automation/automation_proxy_uitest.cc index b4b68b4..d31fdbf 100644 --- a/chrome/test/automation/automation_proxy_uitest.cc +++ b/chrome/test/automation/automation_proxy_uitest.cc @@ -808,13 +808,13 @@ void ExternalTabUITestMockClient::NavigateInExternalTab(int tab_handle, } void ExternalTabUITestMockClient::ConnectToExternalTab(gfx::NativeWindow parent, - intptr_t cookie) { + const IPC::AttachExternalTabParams& attach_params) { gfx::NativeWindow tab_container = NULL; gfx::NativeWindow tab_window = NULL; int tab_handle = 0; - IPC::SyncMessage* message = new AutomationMsg_ConnectExternalTab(0, cookie, - &tab_container, &tab_window, &tab_handle); + IPC::SyncMessage* message = new AutomationMsg_ConnectExternalTab(0, + attach_params.cookie, true, &tab_container, &tab_window, &tab_handle); channel_->Send(message); RECT rect; @@ -1276,12 +1276,12 @@ TEST_F(ExternalTabUITestPopupEnabled, WindowDotOpen) { CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL); - EXPECT_CALL(*mock_, OnAttachExternalTab(1, _, _)) + EXPECT_CALL(*mock_, OnAttachExternalTab(1, _)) .Times(1) .WillOnce(testing::WithArgs<1>(testing::Invoke(CreateFunctor(mock_, &ExternalTabUITestMockClient::ConnectToExternalTab, popup1_host)))); - EXPECT_CALL(*mock_, OnAttachExternalTab(2, _, _)) + EXPECT_CALL(*mock_, OnAttachExternalTab(2, _)) .Times(1) .WillOnce(testing::WithArgs<1>(testing::Invoke(CreateFunctor(mock_, &ExternalTabUITestMockClient::ConnectToExternalTab, popup2_host)))); @@ -1327,7 +1327,7 @@ TEST_F(ExternalTabUITestPopupEnabled, UserGestureTargetBlank) { .WillOnce(testing::InvokeWithoutArgs(testing::CreateFunctor(mock_, &ExternalTabUITestMockClient::NavigateThroughUserGesture))); - EXPECT_CALL(*mock_, OnAttachExternalTab(1, _, _)) + EXPECT_CALL(*mock_, OnAttachExternalTab(1, _)) .Times(1) .WillOnce(testing::WithArgs<1>(testing::Invoke(CreateFunctor(mock_, &ExternalTabUITestMockClient::ConnectToExternalTab, foo_host)))); diff --git a/chrome/test/automation/automation_proxy_uitest.h b/chrome/test/automation/automation_proxy_uitest.h index 27210ce..56d4054 100644 --- a/chrome/test/automation/automation_proxy_uitest.h +++ b/chrome/test/automation/automation_proxy_uitest.h @@ -55,11 +55,11 @@ class ExternalTabUITestMockClient : public AutomationProxy { MOCK_METHOD4(OnOpenURL, void(int tab_handle, const GURL& url, - const GURL& referrer, int open_disposition)); + const GURL& referrer, int open_disposition)); MOCK_METHOD3(OnNavigationStateChanged, void(int tab_handle, int flags, - const IPC::NavigationInfo& nav_info)); - MOCK_METHOD3(OnAttachExternalTab, void(int tab_handle, intptr_t cookie, - int disposition)); + const IPC::NavigationInfo& nav_info)); + MOCK_METHOD2(OnAttachExternalTab, void(int tab_handle, + const IPC::AttachExternalTabParams& params)); MOCK_METHOD2(OnLoad, void(int tab_handle, const GURL&url)); @@ -84,7 +84,8 @@ class ExternalTabUITestMockClient : public AutomationProxy { void NavigateThroughUserGesture(); void IgnoreFavIconNetworkRequest(); - void ConnectToExternalTab(gfx::NativeWindow parent, intptr_t cookie); + void ConnectToExternalTab(gfx::NativeWindow parent, + const IPC::AttachExternalTabParams& attach_params); // Helper for network requests. void ServeHTMLData(int tab_handle, const GURL& url, const std::string& data); // Destroys the host window. diff --git a/chrome_frame/chrome_active_document.cc b/chrome_frame/chrome_active_document.cc index 4da4056e..ce1897f 100644 --- a/chrome_frame/chrome_active_document.cc +++ b/chrome_frame/chrome_active_document.cc @@ -207,6 +207,8 @@ STDMETHODIMP ChromeActiveDocument::Load(BOOL fully_avalable, if (client_site) { SetClientSite(client_site); + DoQueryService(IID_INewWindowManager, client_site, + popup_manager_.Receive()); } Bho* chrome_frame_bho = Bho::GetCurrentThreadBhoInstance(); @@ -678,7 +680,7 @@ void ChromeActiveDocument::OnViewSource() { DCHECK(navigation_info_.url.is_valid()); std::string url_to_open = "view-source:"; url_to_open += navigation_info_.url.spec(); - OnOpenURL(0, GURL(url_to_open), GURL(), NEW_WINDOW); + HostNavigate(GURL(url_to_open), GURL(), NEW_WINDOW); } void ChromeActiveDocument::OnDetermineSecurityZone(const GUID* cmd_group_guid, @@ -710,6 +712,27 @@ void ChromeActiveDocument::OnOpenURL(int tab_handle, Base::OnOpenURL(tab_handle, url_to_open, referrer, open_disposition); } +void ChromeActiveDocument::OnAttachExternalTab(int tab_handle, + const IPC::AttachExternalTabParams& params) { + DWORD flags = 0; + if (params.user_gesture) + flags = NWMF_USERREQUESTED; + + HRESULT hr = S_OK; + if (popup_manager_) { + hr = popup_manager_->EvaluateNewWindow( + UTF8ToWide(params.url.spec()).c_str(), NULL, url_, NULL, FALSE, flags, + 0); + } + // Allow popup + if (hr == S_OK) { + Base::OnAttachExternalTab(tab_handle, params); + return; + } + + automation_client_->BlockExternalTab(params.cookie); +} + bool ChromeActiveDocument::PreProcessContextMenu(HMENU menu) { ScopedComPtr<IBrowserService> browser_service; ScopedComPtr<ITravelLog> travel_log; @@ -867,11 +890,11 @@ bool ChromeActiveDocument::LaunchUrl(const std::wstring& url, // Skip over kChromeAttachExternalTabPrefix tokenizer.GetNext(); - intptr_t external_tab_cookie = 0; - - if (tokenizer.GetNext()) - StringToInt(tokenizer.token(), - reinterpret_cast<int*>(&external_tab_cookie)); + uint64 external_tab_cookie = 0; + if (tokenizer.GetNext()) { + wchar_t* end_ptr = 0; + external_tab_cookie = _wcstoui64(tokenizer.token().c_str(), &end_ptr, 10); + } if (external_tab_cookie == 0) { NOTREACHED() << "invalid url for attach tab: " << url; diff --git a/chrome_frame/chrome_active_document.h b/chrome_frame/chrome_active_document.h index e7a4397..68c5c45 100644 --- a/chrome_frame/chrome_active_document.h +++ b/chrome_frame/chrome_active_document.h @@ -252,7 +252,8 @@ END_EXEC_COMMAND_MAP() // ChromeFrameActivexBase overrides virtual void OnOpenURL(int tab_handle, const GURL& url_to_open, const GURL& referrer, int open_disposition); - + virtual void OnAttachExternalTab(int tab_handle, + const IPC::AttachExternalTabParams& params); virtual void OnGoToHistoryEntryOffset(int tab_handle, int offset); // A helper method that updates our internal navigation state @@ -329,7 +330,7 @@ END_EXEC_COMMAND_MAP() bool is_automation_client_reused_; ScopedComPtr<IInternetSecurityManager> security_manager_; - + ScopedComPtr<INewWindowManager> popup_manager_; HACCEL accelerator_table_; public: diff --git a/chrome_frame/chrome_frame_activex_base.h b/chrome_frame/chrome_frame_activex_base.h index 1826fd5..4437a9d 100644 --- a/chrome_frame/chrome_frame_activex_base.h +++ b/chrome_frame/chrome_frame_activex_base.h @@ -300,7 +300,7 @@ END_MSG_MAP() const IPC::ContextMenuParams& params) { if (cmd == IDC_ABOUT_CHROME_FRAME) { int tab_handle = automation_client_->tab()->handle(); - OnOpenURL(tab_handle, GURL("about:version"), GURL(), NEW_WINDOW); + HostNavigate(GURL("about:version"), GURL(), NEW_WINDOW); return true; } else { switch (cmd) { @@ -380,92 +380,8 @@ END_MSG_MAP() virtual void OnOpenURL(int tab_handle, const GURL& url_to_open, const GURL& referrer, int open_disposition) { - ScopedComPtr<IWebBrowser2> web_browser2; - DoQueryService(SID_SWebBrowserApp, m_spClientSite, web_browser2.Receive()); - DCHECK(web_browser2); - - ScopedVariant url; - // Check to see if the URL uses a "view-source:" prefix, if so, open it - // using chrome frame full tab mode by using 'cf:' protocol handler. - // Also change the disposition to NEW_WINDOW since IE6 doesn't have tabs. - if (url_to_open.has_scheme() && - (url_to_open.SchemeIs(chrome::kViewSourceScheme) || - url_to_open.SchemeIs(chrome::kAboutScheme))) { - std::wstring chrome_url; - chrome_url.append(kChromeProtocolPrefix); - chrome_url.append(UTF8ToWide(url_to_open.spec())); - url.Set(chrome_url.c_str()); - open_disposition = NEW_WINDOW; - } else { - url.Set(UTF8ToWide(url_to_open.spec()).c_str()); - } - - VARIANT flags = { VT_I4 }; - V_I4(&flags) = 0; - - IEVersion ie_version = GetIEVersion(); - DCHECK(ie_version != NON_IE && ie_version != IE_UNSUPPORTED); - // Since IE6 doesn't support tabs, so we just use window instead. - if (ie_version == IE_6) { - if (open_disposition == NEW_FOREGROUND_TAB || - open_disposition == NEW_BACKGROUND_TAB || - open_disposition == NEW_WINDOW || - open_disposition == NEW_POPUP) { - V_I4(&flags) = navOpenInNewWindow; - } else if (open_disposition != CURRENT_TAB) { - NOTREACHED() << "Unsupported open disposition in IE6"; - } - } else { - switch (open_disposition) { - case NEW_FOREGROUND_TAB: - V_I4(&flags) = navOpenInNewTab; - break; - case NEW_BACKGROUND_TAB: - V_I4(&flags) = navOpenInBackgroundTab; - break; - case NEW_WINDOW: - case NEW_POPUP: - V_I4(&flags) = navOpenInNewWindow; - break; - default: - break; - } - } - - // TODO(sanjeevr): The navOpenInNewWindow flag causes IE to open this - // in a new window ONLY if the user has specified - // "Always open popups in a new window". Otherwise it opens in a new tab. - // We need to investigate more and see if we can force IE to display the - // link in a new window. MSHTML uses the below code to force an open in a - // new window. But this logic also fails for us. Perhaps this flag is not - // honoured if the ActiveDoc is not MSHTML. - // Even the HLNF_DISABLEWINDOWRESTRICTIONS flag did not work. - // Start of MSHTML-like logic. - // CComQIPtr<ITargetFramePriv2> target_frame = web_browser2; - // if (target_frame) { - // CComPtr<IUri> uri; - // CreateUri(UTF8ToWide(open_url_command->url_.spec()).c_str(), - // Uri_CREATE_IE_SETTINGS, 0, &uri); - // CComPtr<IBindCtx> bind_ctx; - // CreateBindCtx(0, &bind_ctx); - // target_frame->AggregatedNavigation2( - // HLNF_TRUSTFIRSTDOWNLOAD|HLNF_OPENINNEWWINDOW, bind_ctx, NULL, - // L"No_Name", uri, L""); - // } - // End of MSHTML-like logic - VARIANT empty = ScopedVariant::kEmptyVariant; - ScopedVariant http_headers; - - if (referrer.is_valid()) { - std::wstring referrer_header = L"Referer: "; - referrer_header += UTF8ToWide(referrer.spec()); - referrer_header += L"\r\n\r\n"; - http_headers.Set(referrer_header.c_str()); - } - - web_browser2->Navigate2(url.AsInput(), &flags, &empty, &empty, - http_headers.AsInput()); - web_browser2->put_Visible(VARIANT_TRUE); + DCHECK_EQ(CURRENT_TAB, open_disposition); + HostNavigate(url_to_open, referrer, open_disposition); } virtual void OnDownloadRequestInHost(int tab_handle, int request_id) { @@ -538,12 +454,11 @@ END_MSG_MAP() } virtual void OnAttachExternalTab(int tab_handle, - intptr_t cookie, - int disposition) { + const IPC::AttachExternalTabParams& params) { std::string url; - url = StringPrintf("%lsattach_external_tab&%d&%d", kChromeProtocolPrefix, - cookie, disposition); - OnOpenURL(tab_handle, GURL(url), GURL(), disposition); + url = StringPrintf("%lsattach_external_tab&%ls&%d", kChromeProtocolPrefix, + Uint64ToWString(params.cookie).c_str(), params.disposition); + HostNavigate(GURL(url), GURL(), params.disposition); } virtual void OnHandleContextMenu(int tab_handle, HANDLE menu_handle, @@ -1095,6 +1010,96 @@ END_MSG_MAP() } protected: + void HostNavigate(const GURL& url_to_open, + const GURL& referrer, int open_disposition) { + ScopedComPtr<IWebBrowser2> web_browser2; + DoQueryService(SID_SWebBrowserApp, m_spClientSite, web_browser2.Receive()); + DCHECK(web_browser2); + + ScopedVariant url; + // Check to see if the URL uses a "view-source:" prefix, if so, open it + // using chrome frame full tab mode by using 'cf:' protocol handler. + // Also change the disposition to NEW_WINDOW since IE6 doesn't have tabs. + if (url_to_open.has_scheme() && + (url_to_open.SchemeIs(chrome::kViewSourceScheme) || + url_to_open.SchemeIs(chrome::kAboutScheme))) { + std::wstring chrome_url; + chrome_url.append(kChromeProtocolPrefix); + chrome_url.append(UTF8ToWide(url_to_open.spec())); + url.Set(chrome_url.c_str()); + open_disposition = NEW_WINDOW; + } else { + url.Set(UTF8ToWide(url_to_open.spec()).c_str()); + } + + VARIANT flags = { VT_I4 }; + V_I4(&flags) = 0; + + IEVersion ie_version = GetIEVersion(); + DCHECK(ie_version != NON_IE && ie_version != IE_UNSUPPORTED); + // Since IE6 doesn't support tabs, so we just use window instead. + if (ie_version == IE_6) { + if (open_disposition == NEW_FOREGROUND_TAB || + open_disposition == NEW_BACKGROUND_TAB || + open_disposition == NEW_WINDOW || + open_disposition == NEW_POPUP) { + V_I4(&flags) = navOpenInNewWindow; + } else if (open_disposition != CURRENT_TAB) { + NOTREACHED() << "Unsupported open disposition in IE6"; + } + } else { + switch (open_disposition) { + case NEW_FOREGROUND_TAB: + V_I4(&flags) = navOpenInNewTab; + break; + case NEW_BACKGROUND_TAB: + V_I4(&flags) = navOpenInBackgroundTab; + break; + case NEW_WINDOW: + case NEW_POPUP: + V_I4(&flags) = navOpenInNewWindow; + break; + default: + break; + } + } + + // TODO(sanjeevr): The navOpenInNewWindow flag causes IE to open this + // in a new window ONLY if the user has specified + // "Always open popups in a new window". Otherwise it opens in a new tab. + // We need to investigate more and see if we can force IE to display the + // link in a new window. MSHTML uses the below code to force an open in a + // new window. But this logic also fails for us. Perhaps this flag is not + // honoured if the ActiveDoc is not MSHTML. + // Even the HLNF_DISABLEWINDOWRESTRICTIONS flag did not work. + // Start of MSHTML-like logic. + // CComQIPtr<ITargetFramePriv2> target_frame = web_browser2; + // if (target_frame) { + // CComPtr<IUri> uri; + // CreateUri(UTF8ToWide(open_url_command->url_.spec()).c_str(), + // Uri_CREATE_IE_SETTINGS, 0, &uri); + // CComPtr<IBindCtx> bind_ctx; + // CreateBindCtx(0, &bind_ctx); + // target_frame->AggregatedNavigation2( + // HLNF_TRUSTFIRSTDOWNLOAD|HLNF_OPENINNEWWINDOW, bind_ctx, NULL, + // L"No_Name", uri, L""); + // } + // End of MSHTML-like logic + VARIANT empty = ScopedVariant::kEmptyVariant; + ScopedVariant http_headers; + + if (referrer.is_valid()) { + std::wstring referrer_header = L"Referer: "; + referrer_header += UTF8ToWide(referrer.spec()); + referrer_header += L"\r\n\r\n"; + http_headers.Set(referrer_header.c_str()); + } + + web_browser2->Navigate2(url.AsInput(), &flags, &empty, &empty, + http_headers.AsInput()); + web_browser2->put_Visible(VARIANT_TRUE); + } + ScopedBstr url_; ScopedComPtr<IOleDocumentSite> doc_site_; diff --git a/chrome_frame/chrome_frame_automation.cc b/chrome_frame/chrome_frame_automation.cc index 94a82a0..45fa452 100644 --- a/chrome_frame/chrome_frame_automation.cc +++ b/chrome_frame/chrome_frame_automation.cc @@ -253,6 +253,8 @@ void ProxyFactory::CreateProxy(ProxyFactory::ProxyCacheEntry* entry, // Chrome Frame never wants Chrome to start up with a First Run UI. command_line->AppendSwitch(switches::kNoFirstRun); + command_line->AppendSwitch(switches::kDisablePopupBlocking); + // Disable the "Whoa! Chrome has crashed." dialog, because that isn't very // useful for Chrome Frame users. #ifndef NDEBUG @@ -433,7 +435,7 @@ ChromeFrameAutomationClient::ChromeFrameAutomationClient() proxy_factory_(g_proxy_factory.get()), handle_top_level_requests_(false), tab_handle_(-1), - external_tab_cookie_(NULL), + external_tab_cookie_(0), url_fetcher_(NULL), navigate_after_initialization_(false) { } @@ -839,15 +841,15 @@ void ChromeFrameAutomationClient::LaunchComplete( // If we have a valid tab_handle here it means that we are attaching to // an existing ExternalTabContainer instance, in which case we don't // want to create an external tab instance in Chrome. - if (external_tab_cookie_ == NULL) { + if (external_tab_cookie_ == 0) { // Continue with Initialization - Create external tab CreateExternalTab(); } else { // Send a notification to Chrome that we are ready to connect to the // ExternalTab. IPC::SyncMessage* message = - new AutomationMsg_ConnectExternalTab(0, external_tab_cookie_, NULL, - NULL, NULL); + new AutomationMsg_ConnectExternalTab(0, external_tab_cookie_, true, + NULL, NULL, NULL); automation_server_->SendAsAsync(message, NewCallback(this, &ChromeFrameAutomationClient::CreateExternalTabComplete), this); } @@ -1110,13 +1112,20 @@ bool ChromeFrameAutomationClient::Reinitialize( } void ChromeFrameAutomationClient::AttachExternalTab( - intptr_t external_tab_cookie) { + uint64 external_tab_cookie) { DCHECK_EQ(static_cast<TabProxy*>(NULL), tab_.get()); DCHECK_EQ(-1, tab_handle_); external_tab_cookie_ = external_tab_cookie; } +void ChromeFrameAutomationClient::BlockExternalTab(uint64 cookie) { + // The host does not want this tab to be shown (due popup blocker). + IPC::SyncMessage* message = + new AutomationMsg_ConnectExternalTab(0, cookie, false, NULL, NULL, NULL); + automation_server_->SendAsAsync(message, NULL, this); +} + void ChromeFrameAutomationClient::SetPageFontSize( enum AutomationPageFontSize font_size) { if (font_size < SMALLEST_FONT || diff --git a/chrome_frame/chrome_frame_automation.h b/chrome_frame/chrome_frame_automation.h index 9c5b186..567a0c4 100644 --- a/chrome_frame/chrome_frame_automation.h +++ b/chrome_frame/chrome_frame_automation.h @@ -253,7 +253,8 @@ class ChromeFrameAutomationClient PluginUrlRequestManager* url_fetcher); // Attaches an existing external tab to this automation client instance. - void AttachExternalTab(intptr_t external_tab_cookie); + void AttachExternalTab(uint64 external_tab_cookie); + void BlockExternalTab(uint64 cookie); void SetPageFontSize(enum AutomationPageFontSize); @@ -330,7 +331,7 @@ class ChromeFrameAutomationClient ProxyFactory* proxy_factory_; int tab_handle_; // Only used if we attach to an existing tab. - intptr_t external_tab_cookie_; + uint64 external_tab_cookie_; // Set to true if we received a navigation request prior to the automation // server being initialized. diff --git a/chrome_frame/chrome_frame_delegate.h b/chrome_frame/chrome_frame_delegate.h index d577dfd..a235bcd 100644 --- a/chrome_frame/chrome_frame_delegate.h +++ b/chrome_frame/chrome_frame_delegate.h @@ -110,8 +110,8 @@ class ChromeFrameDelegateImpl : public ChromeFrameDelegate { virtual void OnDownloadRequestInHost(int tab_handle, int request_id) {} virtual void OnSetCookieAsync(int tab_handle, const GURL& url, const std::string& cookie) {} - virtual void OnAttachExternalTab(int tab_handle, intptr_t cookie, - int disposition) {} + virtual void OnAttachExternalTab(int tab_handle, + const IPC::AttachExternalTabParams& attach_params) {} virtual void OnGoToHistoryEntryOffset(int tab_handle, int offset) {} virtual void OnGetCookiesFromHost(int tab_handle, const GURL& url, diff --git a/chrome_frame/chrome_launcher.cc b/chrome_frame/chrome_launcher.cc index c5c43ef..374f47f 100644 --- a/chrome_frame/chrome_launcher.cc +++ b/chrome_frame/chrome_launcher.cc @@ -29,6 +29,7 @@ const char* kAllowedSwitches[] = { switches::kNoErrorDialogs, switches::kNoFirstRun, switches::kUserDataDir, + switches::kDisablePopupBlocking, }; CommandLine* CreateLaunchCommandLine() { |