diff options
-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 |