diff options
author | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-06 22:53:06 +0000 |
---|---|---|
committer | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-06 22:53:06 +0000 |
commit | 52622ca1f4b0f04dfbe1d2bc4cd27018a7c7e5b6 (patch) | |
tree | 163a805063d73947bc8bddec43262836e130cdc0 /chrome_frame | |
parent | 174cf0c7c20edf63af4328023a56bf3c2c421c99 (diff) | |
download | chromium_src-52622ca1f4b0f04dfbe1d2bc4cd27018a7c7e5b6.zip chromium_src-52622ca1f4b0f04dfbe1d2bc4cd27018a7c7e5b6.tar.gz chromium_src-52622ca1f4b0f04dfbe1d2bc4cd27018a7c7e5b6.tar.bz2 |
Popups opened with the noreferrer parameter within ChromeFrame should open in the host browser.
This support already exists in Chrome where the renderer routes the url back to the browser
and eventually to the TabContentsDelegate.
However in ChromeFrame if the current window is a popup window then attempting to open this URL
in a tab fails on IE7 and IE8 as popups don't support this functionality. Workaround as per
msdn documentation is to reissue the navigation request with the navOpenInNewWindow flag.
Fixed a bug in the ChromeFrame tests IEEventSink::GetRendererWindow function where at times
it would fail to return the correct HWND in the window hierarchy when the page was rendered
in ChromeFrame.
Fixes bug http://code.google.com/p/chromium/issues/detail?id=68183
BUG=68183
TEST=Covered by new ChromeFrame test.
Review URL: http://codereview.chromium.org/6002017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@70676 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame')
-rw-r--r-- | chrome_frame/chrome_frame_activex_base.h | 17 | ||||
-rw-r--r-- | chrome_frame/test/data/open_href_target_no_referrer.html | 11 | ||||
-rw-r--r-- | chrome_frame/test/ie_event_sink.cc | 12 | ||||
-rw-r--r-- | chrome_frame/test/mock_ie_event_sink_actions.h | 6 | ||||
-rw-r--r-- | chrome_frame/test/navigation_test.cc | 81 |
5 files changed, 121 insertions, 6 deletions
diff --git a/chrome_frame/chrome_frame_activex_base.h b/chrome_frame/chrome_frame_activex_base.h index cedd526..324c1f1 100644 --- a/chrome_frame/chrome_frame_activex_base.h +++ b/chrome_frame/chrome_frame_activex_base.h @@ -1224,8 +1224,21 @@ END_MSG_MAP() http_headers.Set(referrer_header.c_str()); } - web_browser2->Navigate2(url.AsInput(), &flags, &empty, &empty, - http_headers.AsInput()); + HRESULT hr = web_browser2->Navigate2(url.AsInput(), &flags, &empty, &empty, + http_headers.AsInput()); + // If the current window is a popup window then attempting to open a new + // tab for the navigation will fail. We attempt to issue the navigation in + // a new window in this case. + // http://msdn.microsoft.com/en-us/library/aa752133(v=vs.85).aspx + if (FAILED(hr) && V_I4(&flags) != navOpenInNewWindow) { + V_I4(&flags) = navOpenInNewWindow; + hr = web_browser2->Navigate2(url.AsInput(), &flags, &empty, &empty, + http_headers.AsInput()); + + DLOG_IF(ERROR, FAILED(hr)) + << "Navigate2 failed with error: " + << base::StringPrintf("0x%08X", hr); + } } void InitializeAutomationSettings() { diff --git a/chrome_frame/test/data/open_href_target_no_referrer.html b/chrome_frame/test/data/open_href_target_no_referrer.html new file mode 100644 index 0000000..33834bf --- /dev/null +++ b/chrome_frame/test/data/open_href_target_no_referrer.html @@ -0,0 +1,11 @@ +<html> + <head> + <title>Chrome frame window opened by window.open()</title> + <meta http-equiv="X-UA-Compatible" content="IE=7,chrome=1" /> + </head> + + <body> + <a href="simple.html" rel="noreferrer" target="_blank"> + rel="noreferrer"</a> + </body> +</html> diff --git a/chrome_frame/test/ie_event_sink.cc b/chrome_frame/test/ie_event_sink.cc index 49f56f4..1649e2a 100644 --- a/chrome_frame/test/ie_event_sink.cc +++ b/chrome_frame/test/ie_event_sink.cc @@ -266,14 +266,18 @@ HWND IEEventSink::GetRendererWindow() { ole_window->GetWindow(&activex_window); EXPECT_TRUE(IsWindow(activex_window)); + wchar_t class_name[MAX_PATH] = {0}; + HWND child_window = NULL; // chrome tab window is the first (and the only) child of activex for (HWND first_child = activex_window; ::IsWindow(first_child); first_child = ::GetWindow(first_child, GW_CHILD)) { - renderer_window = first_child; + child_window = first_child; + GetClassName(child_window, class_name, arraysize(class_name)); + if (!_wcsicmp(class_name, L"Chrome_RenderWidgetHostHWND")) { + renderer_window = child_window; + break; + } } - wchar_t class_name[MAX_PATH] = {0}; - GetClassName(renderer_window, class_name, arraysize(class_name)); - EXPECT_EQ(0, _wcsicmp(class_name, L"Chrome_RenderWidgetHostHWND")); } } else { DCHECK(web_browser2_); diff --git a/chrome_frame/test/mock_ie_event_sink_actions.h b/chrome_frame/test/mock_ie_event_sink_actions.h index a3dc60c..2d5539d 100644 --- a/chrome_frame/test/mock_ie_event_sink_actions.h +++ b/chrome_frame/test/mock_ie_event_sink_actions.h @@ -169,6 +169,12 @@ ACTION_P2(AccDoDefaultActionInRenderer, mock, matcher) { mock->event_sink()->GetRendererWindow()); } +ACTION_P3(DelayAccDoDefaultActionInRenderer, mock, matcher, delay) { + SleepEx(delay, false); + AccInWindow<void>(AccDoDefaultAction(matcher), + mock->event_sink()->GetRendererWindow()); +} + ACTION_P2(AccLeftClickInBrowser, mock, matcher) { AccInWindow<void>(AccLeftClick(matcher), mock->event_sink()->GetBrowserWindow()); diff --git a/chrome_frame/test/navigation_test.cc b/chrome_frame/test/navigation_test.cc index ff47ba5..fea6387 100644 --- a/chrome_frame/test/navigation_test.cc +++ b/chrome_frame/test/navigation_test.cc @@ -1171,4 +1171,85 @@ TEST_P(FullTabNavigationTest, RefreshContentsUATest) { LaunchIEAndNavigate(src_url); } +// Link navigations in the same domain specified with the noreferrer flag +// should be opened in the host browser. +TEST_F(FullTabNavigationTest, JavascriptWindowOpenNoReferrerOpensInHost) { + // Please see http://code.google.com/p/chromium/issues/detail?id=60987 + // for more information on why this test is disabled for Vista with IE7. + if (base::win::GetVersion() == base::win::VERSION_VISTA && + GetInstalledIEVersion() == IE_7) { + LOG(INFO) << "Not running test on Vista with IE7"; + return; + } + + MockAccEventObserver acc_observer; + + testing::StrictMock<MockIEEventSink> new_window_mock; + testing::StrictMock<MockIEEventSink> + no_referrer_target_opener_window_mock; + + std::wstring initial_url = + GetTestUrl(L"window_open.html?open_href_target_no_referrer.html"); + + std::wstring parent_url = GetTestUrl( + L"open_href_target_no_referrer.html"); + + std::wstring new_window_url = GetSimplePageUrl(); + + ie_mock_.ExpectNavigation(false, initial_url); + EXPECT_CALL(ie_mock_, OnLoad(false, StrEq(initial_url))); + + EXPECT_CALL(acc_observer, OnAccDocLoad(_)) + .WillOnce(AccLeftClick(AccObjectMatcher())) + .WillRepeatedly(testing::Return()); + + ie_mock_.ExpectNewWindow(&no_referrer_target_opener_window_mock); + + no_referrer_target_opener_window_mock.ExpectNavigation(true, parent_url); + + server_mock_.ExpectAndServeRequest(CFInvocation::MetaTag(), parent_url); + server_mock_.ExpectAndServeRequest(CFInvocation::None(), new_window_url); + server_mock_.ExpectAndServeRequest(CFInvocation::None(), initial_url); + + EXPECT_CALL(no_referrer_target_opener_window_mock, + OnLoad(false, StrEq(parent_url))) + .Times(testing::AnyNumber()); + + EXPECT_CALL(no_referrer_target_opener_window_mock, + OnLoad(true, StrEq(parent_url))) + .WillOnce(DelayAccDoDefaultActionInRenderer( + &no_referrer_target_opener_window_mock, + AccObjectMatcher(L"", L"link"), 1000)); + + // The parent window is in CF and opens a child window with the no referrer + // flag in which case it should open in IE. + no_referrer_target_opener_window_mock.ExpectNewWindow(&new_window_mock); + new_window_mock.ExpectNavigation(false, new_window_url); + + EXPECT_CALL(new_window_mock, OnFileDownload(_, _)) + .Times(testing::AnyNumber()); + + EXPECT_CALL(new_window_mock, + OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, + testing::HasSubstr(L"attach")), + _, _, _, _, _)); + EXPECT_CALL(new_window_mock, + OnNavigateComplete2(_, testing::Field(&VARIANT::bstrVal, + testing::HasSubstr(L"attach")))) + .Times(testing::AtMost(1)); + + EXPECT_CALL(new_window_mock, OnLoad(false, StrEq(new_window_url))) + .WillOnce(CloseBrowserMock(&new_window_mock)); + + EXPECT_CALL(new_window_mock, OnQuit()) + .WillOnce(CloseBrowserMock( + &no_referrer_target_opener_window_mock)); + + EXPECT_CALL(no_referrer_target_opener_window_mock, OnQuit()) + .WillOnce(CloseBrowserMock(&ie_mock_)); + + LaunchIENavigateAndLoop(initial_url, + kChromeFrameLongNavigationTimeoutInSeconds); +} + } // namespace chrome_frame_test |