summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-08 16:26:11 +0000
committerstoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-08 16:26:11 +0000
commitb1c5563861d33febd3ba84dfac70c7b6921bda26 (patch)
tree8f7f9747e59f42cf0878edb8e599a3151e944045
parent57fc471c6864dea93852742643e32d35a30c8559 (diff)
downloadchromium_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.h3
-rw-r--r--chrome/browser/automation/automation_provider_win.cc7
-rw-r--r--chrome/browser/external_tab_container.cc20
-rw-r--r--chrome/browser/external_tab_container.h4
-rw-r--r--chrome/test/automation/automation_messages.h41
-rw-r--r--chrome/test/automation/automation_messages_internal.h12
-rw-r--r--chrome/test/automation/automation_proxy_uitest.cc12
-rw-r--r--chrome/test/automation/automation_proxy_uitest.h11
-rw-r--r--chrome_frame/chrome_active_document.cc35
-rw-r--r--chrome_frame/chrome_active_document.h5
-rw-r--r--chrome_frame/chrome_frame_activex_base.h189
-rw-r--r--chrome_frame/chrome_frame_automation.cc19
-rw-r--r--chrome_frame/chrome_frame_automation.h5
-rw-r--r--chrome_frame/chrome_frame_delegate.h4
-rw-r--r--chrome_frame/chrome_launcher.cc1
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() {