diff options
Diffstat (limited to 'chrome_frame')
-rw-r--r-- | chrome_frame/chrome_active_document.cc | 17 | ||||
-rw-r--r-- | chrome_frame/chrome_active_document.h | 4 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_activex_base.h | 16 | ||||
-rw-r--r-- | chrome_frame/chrome_protocol.rgs | 2 | ||||
-rw-r--r-- | chrome_frame/chrome_tab.cc | 26 | ||||
-rw-r--r-- | chrome_frame/test/chrome_frame_test_utils.cc | 52 | ||||
-rw-r--r-- | chrome_frame/test/chrome_frame_test_utils.h | 37 | ||||
-rw-r--r-- | chrome_frame/test/chrome_frame_unittests.cc | 133 | ||||
-rw-r--r-- | chrome_frame/test/data/cf_protocol.html | 2 | ||||
-rw-r--r-- | chrome_frame/test/data/chrome_frame_tester_helpers.js | 2 | ||||
-rw-r--r-- | chrome_frame/test/data/navigate_out.html | 2 | ||||
-rw-r--r-- | chrome_frame/test/reliability/page_load_test.cc | 8 | ||||
-rw-r--r-- | chrome_frame/utils.cc | 3 | ||||
-rw-r--r-- | chrome_frame/utils.h | 4 |
14 files changed, 249 insertions, 59 deletions
diff --git a/chrome_frame/chrome_active_document.cc b/chrome_frame/chrome_active_document.cc index 202128b..091f0ba 100644 --- a/chrome_frame/chrome_active_document.cc +++ b/chrome_frame/chrome_active_document.cc @@ -40,8 +40,7 @@ const wchar_t kChromeAttachExternalTabPrefix[] = L"attach_external_tab"; static const wchar_t kUseChromeNetworking[] = L"UseChromeNetworking"; -static const wchar_t kHandleTopLevelRequests[] = - L"HandleTopLevelRequests"; +static const wchar_t kHandleTopLevelRequests[] = L"HandleTopLevelRequests"; DEFINE_GUID(CGID_DocHostCmdPriv, 0x000214D4L, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46); @@ -821,6 +820,20 @@ bool ChromeActiveDocument::ParseUrl(const std::wstring& url, return false; } + if (*is_chrome_protocol) { + // Allow chrome protocol (gcf:) if - + // - explicitly enabled using registry + // - for gcf:attach_external_tab + // - for gcf:about and gcf:view-source + GURL crack_url(initial_url); + bool allow_gcf_protocol = !*is_new_navigation || + GetConfigBool(false, kEnableGCFProtocol) || + crack_url.SchemeIs(chrome::kAboutScheme) || + crack_url.SchemeIs(chrome::kViewSourceScheme); + if (!allow_gcf_protocol) + return false; + } + *parsed_url = initial_url; return true; } diff --git a/chrome_frame/chrome_active_document.h b/chrome_frame/chrome_active_document.h index dc6511d..eed38e7 100644 --- a/chrome_frame/chrome_active_document.h +++ b/chrome_frame/chrome_active_document.h @@ -47,8 +47,6 @@ class ChromeActiveDocument; // current travel log entry #define INTERNAL_CMDID_REPLACE_CURRENT_TRAVEL_LOG_ENTRY_URL (40) -#define INTERNAL_IE_CONTEXTMENU_VIEWSOURCE (2139) - #ifndef SBCMDID_MIXEDZONE // This command is sent by the frame to allow the document to return the URL // security zone for display. @@ -157,7 +155,7 @@ BEGIN_EXEC_COMMAND_MAP(ChromeActiveDocument) EXEC_COMMAND_HANDLER_GENERIC(OLECMDID_PRINT, automation_client_->PrintTab()) EXEC_COMMAND_HANDLER_NO_ARGS(OLECMDID_FIND, OnFindInPage) EXEC_COMMAND_HANDLER_NO_ARGS(IDM_FIND, OnFindInPage) - EXEC_COMMAND_HANDLER_NO_ARGS(INTERNAL_IE_CONTEXTMENU_VIEWSOURCE, OnViewSource) + EXEC_COMMAND_HANDLER_NO_ARGS(IDM_VIEWSOURCE, OnViewSource) FORWARD_TAB_COMMAND(OLECMDID_SELECTALL, SelectAll) FORWARD_TAB_COMMAND(OLECMDID_CUT, Cut) FORWARD_TAB_COMMAND(OLECMDID_COPY, Copy) diff --git a/chrome_frame/chrome_frame_activex_base.h b/chrome_frame/chrome_frame_activex_base.h index af71a11..fe11b66 100644 --- a/chrome_frame/chrome_frame_activex_base.h +++ b/chrome_frame/chrome_frame_activex_base.h @@ -41,6 +41,7 @@ #include "chrome_frame/com_message_event.h" #include "chrome_frame/com_type_info_holder.h" #include "chrome_frame/urlmon_url_request.h" +#include "chrome/common/url_constants.h" #include "grit/generated_resources.h" #include "net/base/cookie_monster.h" @@ -387,12 +388,13 @@ END_MSG_MAP() // 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("view-source") || - url_to_open.SchemeIs("about"))) { - std::string chrome_url; - chrome_url.append("cf:"); - chrome_url.append(url_to_open.spec()); - url.Set(UTF8ToWide(chrome_url).c_str()); + 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()); @@ -506,7 +508,7 @@ END_MSG_MAP() intptr_t cookie, int disposition) { std::string url; - url = StringPrintf("cf:attach_external_tab&%d&%d", + url = StringPrintf("%lsattach_external_tab&%d&%d", kChromeProtocolPrefix, cookie, disposition); OnOpenURL(tab_handle, GURL(url), GURL(), disposition); } diff --git a/chrome_frame/chrome_protocol.rgs b/chrome_frame/chrome_protocol.rgs index de6a3e2..9546973 100644 --- a/chrome_frame/chrome_protocol.rgs +++ b/chrome_frame/chrome_protocol.rgs @@ -29,7 +29,7 @@ HKLM { NoRemove Classes { NoRemove Protocols { NoRemove Handler { - NoRemove 'cf' { + 'gcf' { val CLSID = s '{9875BFAF-B04D-445E-8A69-BE36838CDE3E}' } } diff --git a/chrome_frame/chrome_tab.cc b/chrome_frame/chrome_tab.cc index 9944f5b..301d9f8 100644 --- a/chrome_frame/chrome_tab.cc +++ b/chrome_frame/chrome_tab.cc @@ -40,6 +40,9 @@ static const wchar_t kBhoRegistryPath[] = const wchar_t kInternetSettings[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"; +const wchar_t kProtocolHandlers[] = + L"Software\\Classes\\Protocols\\Handler"; + const wchar_t kBhoNoLoadExplorerValue[] = L"NoExplorer"; // {0562BFC3-2550-45b4-BD8E-A310583D3A6F} @@ -236,7 +239,6 @@ HRESULT RegisterChromeTabBHO() { DLOG(INFO) << "Registered ChromeTab BHO"; // We now add the chromeframe user agent at runtime. - // SetClockUserAgent(L"1"); RefreshElevationPolicy(); return S_OK; } @@ -270,6 +272,26 @@ HRESULT UnregisterChromeTabBHO() { return S_OK; } +HRESULT CleanupCFProtocol() { + RegKey protocol_handlers_key; + if (protocol_handlers_key.Open(HKEY_LOCAL_MACHINE, kProtocolHandlers, + KEY_READ | KEY_WRITE)) { + RegKey cf_protocol_key; + if (cf_protocol_key.Open(protocol_handlers_key.Handle(), L"cf", + KEY_QUERY_VALUE)) { + std::wstring protocol_clsid_string; + if (cf_protocol_key.ReadValue(L"CLSID", &protocol_clsid_string)) { + CLSID protocol_clsid = {0}; + IIDFromString(protocol_clsid_string.c_str(), &protocol_clsid); + if (IsEqualGUID(protocol_clsid, CLSID_ChromeProtocol)) + protocol_handlers_key.DeleteKey(L"cf"); + } + } + } + + return S_OK; +} + // Used to determine whether the DLL can be unloaded by OLE STDAPI DllCanUnloadNow() { return _AtlModule.DllCanUnloadNow(); @@ -323,6 +345,8 @@ STDAPI DllUnregisterServer() { hr = _AtlModule.UpdateRegistryFromResourceS(IDR_CHROMEFRAME_NPAPI, FALSE); } + // TODO(joshia): Remove after 2 refresh releases + CleanupCFProtocol(); return hr; } diff --git a/chrome_frame/test/chrome_frame_test_utils.cc b/chrome_frame/test/chrome_frame_test_utils.cc index faee92a..0b8176d 100644 --- a/chrome_frame/test/chrome_frame_test_utils.cc +++ b/chrome_frame/test/chrome_frame_test_utils.cc @@ -690,6 +690,13 @@ _ATL_FUNC_INFO WebBrowserEventSink::kBeforeNavigate2Info = { } }; +_ATL_FUNC_INFO WebBrowserEventSink::kNewWindow2Info = { + CC_STDCALL, VT_EMPTY, 2, { + VT_DISPATCH | VT_BYREF, + VT_BOOL | VT_BYREF, + } +}; + _ATL_FUNC_INFO WebBrowserEventSink::kNewWindow3Info = { CC_STDCALL, VT_EMPTY, 5, { VT_DISPATCH | VT_BYREF, @@ -711,6 +718,15 @@ _ATL_FUNC_INFO WebBrowserEventSink::kDocumentCompleteInfo = { }; // WebBrowserEventSink member defines +void WebBrowserEventSink::Attach(IDispatch* browser_disp) { + EXPECT_TRUE(NULL != browser_disp); + if(browser_disp) { + EXPECT_HRESULT_SUCCEEDED(web_browser2_.QueryFrom(browser_disp)); + EXPECT_TRUE(S_OK == DispEventAdvise(web_browser2_, + &DIID_DWebBrowserEvents2)); + } +} + void WebBrowserEventSink::Uninitialize() { DisconnectFromChromeFrame(); if (web_browser2_.get()) { @@ -745,6 +761,34 @@ STDMETHODIMP_(void) WebBrowserEventSink::OnDocumentCompleteInternal( OnDocumentComplete(dispatch, url); } +STDMETHODIMP_(void) WebBrowserEventSink::OnNewWindow3Internal( + IDispatch** dispatch, VARIANT_BOOL* cancel, DWORD flags, BSTR url_context, + BSTR url) { + DLOG(INFO) << __FUNCTION__; + if (!dispatch) { + NOTREACHED() << "Invalid argument - dispatch"; + return; + } + + // Call the OnNewWindow3 with original args + OnNewWindow3(dispatch, cancel, flags, url_context, url); + + // Note that |dispatch| is an [in/out] argument. IE is asking listeners if + // they want to use a IWebBrowser2 of their choice for the new window. + // Since we need to listen on events on the new browser, we create one + // if needed. + if (!*dispatch) { + ScopedComPtr<IDispatch> new_browser; + HRESULT hr = new_browser.CreateInstance(CLSID_InternetExplorer, NULL, + CLSCTX_LOCAL_SERVER); + DCHECK(SUCCEEDED(hr) && new_browser); + *dispatch = new_browser.Detach(); + } + + if (*dispatch) + OnNewBrowserWindow(*dispatch, url); +} + HRESULT WebBrowserEventSink::OnLoadInternal(const VARIANT* param) { DLOG(INFO) << __FUNCTION__ << " " << param->bstrVal; OnLoad(param->bstrVal); @@ -788,14 +832,12 @@ HRESULT WebBrowserEventSink::Navigate(const std::wstring& navigate_url) { } void WebBrowserEventSink::SetFocusToChrome() { - chrome_frame_test::SetKeyboardFocusToWindow( - GetAttachedChromeRendererWindow(), 1, 1); + chrome_frame_test::SetKeyboardFocusToWindow(GetTabWindow(), 1, 1); } void WebBrowserEventSink::SendInputToChrome( const std::string& input_string) { - chrome_frame_test::SendInputToWindow( - GetAttachedChromeRendererWindow(), input_string); + chrome_frame_test::SendInputToWindow(GetTabWindow(), input_string); } void WebBrowserEventSink::ConnectToChromeFrame() { @@ -833,7 +875,7 @@ void WebBrowserEventSink::DisconnectFromChromeFrame() { } } -HWND WebBrowserEventSink::GetAttachedChromeRendererWindow() { +HWND WebBrowserEventSink::GetTabWindow() { DCHECK(chrome_frame_); HWND renderer_window = NULL; ScopedComPtr<IOleWindow> ole_window; diff --git a/chrome_frame/test/chrome_frame_test_utils.h b/chrome_frame/test/chrome_frame_test_utils.h index 57e356c..1cc6e82 100644 --- a/chrome_frame/test/chrome_frame_test_utils.h +++ b/chrome_frame/test/chrome_frame_test_utils.h @@ -177,6 +177,7 @@ class WebBrowserEventSink Uninitialize(); } + void Attach(IDispatch* browser_disp); void Uninitialize(); // Helper function to launch IE and navigate to a URL. @@ -205,8 +206,10 @@ BEGIN_SINK_MAP(WebBrowserEventSink) OnNavigateComplete2Internal, &kNavigateComplete2Info) SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_NAVIGATEERROR, OnNavigateError, &kNavigateErrorInfo) + SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_NEWWINDOW2, + OnNewWindow2, &kNewWindow2Info) SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_NEWWINDOW3, - OnNewWindow3, &kNewWindow3Info) + OnNewWindow3Internal, &kNewWindow3Info) SINK_ENTRY_INFO(0, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentCompleteInternal, &kDocumentCompleteInfo) END_SINK_MAP() @@ -224,21 +227,11 @@ END_SINK_MAP() return S_OK; } - STDMETHOD(OnBeforeNavigate2Internal)(IDispatch* dispatch, VARIANT* url, - VARIANT* flags, - VARIANT* target_frame_name, - VARIANT* post_data, VARIANT* headers, - VARIANT_BOOL* cancel); STDMETHOD_(void, OnDownloadBegin)() {} - STDMETHOD_(void, OnNavigateComplete2Internal)(IDispatch* dispatch, - VARIANT* url); STDMETHOD_(void, OnNavigateComplete2)(IDispatch* dispatch, VARIANT* url) {} - STDMETHOD_(void, OnNewWindow3)(IDispatch** dispatch, VARIANT_BOOL* Cancel, + STDMETHOD_(void, OnNewWindow2)(IDispatch** dispatch, VARIANT_BOOL* cancel) {} + STDMETHOD_(void, OnNewWindow3)(IDispatch** dispatch, VARIANT_BOOL* cancel, DWORD flags, BSTR url_context, BSTR url) {} - - STDMETHOD_(void, OnDocumentCompleteInternal)(IDispatch* dispatch, - VARIANT* url); - STDMETHOD_(void, OnDocumentComplete)(IDispatch* dispatch, VARIANT* url) {} #ifdef _DEBUG @@ -260,9 +253,24 @@ END_SINK_MAP() return web_browser2_.get(); } + virtual void OnNewBrowserWindow(IDispatch* new_window, const wchar_t* url) {} + HRESULT SetWebBrowser(IWebBrowser2* web_browser2); protected: + STDMETHOD(OnBeforeNavigate2Internal)(IDispatch* dispatch, VARIANT* url, + VARIANT* flags, + VARIANT* target_frame_name, + VARIANT* post_data, VARIANT* headers, + VARIANT_BOOL* cancel); + STDMETHOD_(void, OnNavigateComplete2Internal)(IDispatch* dispatch, + VARIANT* url); + STDMETHOD_(void, OnDocumentCompleteInternal)(IDispatch* dispatch, + VARIANT* url); + STDMETHOD_(void, OnNewWindow3Internal)(IDispatch** dispatch, + VARIANT_BOOL* Cancel, DWORD flags, + BSTR url_context, BSTR url); + // IChromeFrame callbacks HRESULT OnLoadInternal(const VARIANT* param); HRESULT OnLoadErrorInternal(const VARIANT* param); @@ -270,7 +278,7 @@ END_SINK_MAP() void ConnectToChromeFrame(); void DisconnectFromChromeFrame(); - HWND GetAttachedChromeRendererWindow(); + HWND GetTabWindow(); public: ScopedComPtr<IWebBrowser2> web_browser2_; @@ -283,6 +291,7 @@ END_SINK_MAP() static _ATL_FUNC_INFO kBeforeNavigate2Info; static _ATL_FUNC_INFO kNavigateComplete2Info; static _ATL_FUNC_INFO kNavigateErrorInfo; + static _ATL_FUNC_INFO kNewWindow2Info; static _ATL_FUNC_INFO kNewWindow3Info; static _ATL_FUNC_INFO kVoidMethodInfo; static _ATL_FUNC_INFO kDocumentCompleteInfo; diff --git a/chrome_frame/test/chrome_frame_unittests.cc b/chrome_frame/test/chrome_frame_unittests.cc index f343ff2c..fa63ab6 100644 --- a/chrome_frame/test/chrome_frame_unittests.cc +++ b/chrome_frame/test/chrome_frame_unittests.cc @@ -9,6 +9,7 @@ // defined. #include <mshtml.h> #include <exdisp.h> +#include <mshtmcid.h> #include "base/basictypes.h" #include "base/file_version_info.h" @@ -24,6 +25,7 @@ #include "chrome_frame/test/chrome_frame_test_utils.h" #include "chrome_frame/test_utils.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/url_constants.h" #include "chrome/installer/util/install_util.h" #include "chrome/installer/util/helper.h" @@ -1238,11 +1240,15 @@ class MockWebBrowserEventSink : public chrome_frame_test::WebBrowserEventSink { MOCK_METHOD5_WITH_CALLTYPE(__stdcall, OnNewWindow3, void (IDispatch** dispatch, // NOLINT - VARIANT_BOOL* Cancel, + VARIANT_BOOL* cancel, DWORD flags, BSTR url_context, BSTR url)); + MOCK_METHOD2_WITH_CALLTYPE(__stdcall, OnNewWindow2, + void (IDispatch** dispatch, // NOLINT + VARIANT_BOOL* cancel)); + MOCK_METHOD5_WITH_CALLTYPE(__stdcall, OnNavigateError, void (IDispatch* dispatch, // NOLINT VARIANT* url, @@ -1253,11 +1259,13 @@ class MockWebBrowserEventSink : public chrome_frame_test::WebBrowserEventSink { MOCK_METHOD1(OnLoad, void (const wchar_t* url)); // NOLINT MOCK_METHOD1(OnLoadError, void (const wchar_t* url)); // NOLINT MOCK_METHOD1(OnMessage, void (const wchar_t* message)); // NOLINT + MOCK_METHOD2(OnNewBrowserWindow, void (IDispatch* dispatch, // NOLINT + const wchar_t* url)); }; using testing::_; -const wchar_t kChromeFrameFileUrl[] = L"cf:file:///C:/"; +const wchar_t kChromeFrameFileUrl[] = L"gcf:file:///C:/"; TEST(ChromeFrameTest, FullTabModeIE_DisallowedUrls) { chrome_frame_test::TimedMsgLoop loop; @@ -1311,16 +1319,11 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_WindowOpenInChrome) { chrome_frame_test::TimedMsgLoop loop; CComObjectStackEx<MockWebBrowserEventSink> mock; - ::testing::InSequence sequence; - EXPECT_CALL(mock, - OnBeforeNavigate2( - _, testing::Field(&VARIANT::bstrVal, - testing::StrCaseEq(kChromeFrameFullTabWindowOpenTestUrl)), - _, _, _, _, _)) - .WillOnce(testing::Return(S_OK)); - EXPECT_CALL(mock, OnNavigateComplete2(_, _)) - .WillOnce(testing::Return()); - + // NOTE: + // Intentionally not in sequence since we have just one navigation + // per mock, it's OK to be not in sequence as long as all the expections + // are satisfied. Moreover, since the second mock expects a new window, + // its events happen in random order. EXPECT_CALL(mock, OnBeforeNavigate2( _, testing::Field(&VARIANT::bstrVal, @@ -1342,8 +1345,30 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_WindowOpenInChrome) { &chrome_frame_test::WebBrowserEventSink::SendInputToChrome, std::string("A")), 0)))); - EXPECT_CALL(mock, - OnNewWindow3(_, _, _, _, _)); + // Watch for new window + CComObjectStackEx<MockWebBrowserEventSink> new_window_mock; + // Can't really check URL here since it will be of the form gcf:attach... + EXPECT_CALL(mock, OnNewWindow3(_, _, _, _, _)); + EXPECT_CALL(mock, OnNewBrowserWindow(_, _)) + .WillOnce(testing::WithArgs<0>( + testing::Invoke(CreateFunctor(&new_window_mock, + &MockWebBrowserEventSink::Attach)))); + + // Expect navigations on the new mock + EXPECT_CALL(new_window_mock, OnBeforeNavigate2(_, _, _, _, _, _, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return(S_OK)); + EXPECT_CALL(new_window_mock, OnNavigateComplete2(_, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return()); + EXPECT_CALL(new_window_mock, + OnLoad(testing::StrEq(kChromeFrameFullTabWindowOpenPopupUrl))) + .WillOnce(testing::DoAll( + testing::InvokeWithoutArgs(CreateFunctor(&mock, + &MockWebBrowserEventSink::Uninitialize)), + testing::InvokeWithoutArgs(CreateFunctor(&new_window_mock, + &MockWebBrowserEventSink::Uninitialize)), + testing::IgnoreResult(testing::InvokeWithoutArgs( + &chrome_frame_test::CloseAllIEWindows)), + QUIT_LOOP_SOON(loop, 2))); HRESULT hr = mock.LaunchIEAndNavigate(kChromeFrameFullTabWindowOpenTestUrl); ASSERT_HRESULT_SUCCEEDED(hr); @@ -1363,10 +1388,10 @@ const wchar_t kSubFrameUrl1[] = L"http://localhost:1337/files/sub_frame1.html"; const wchar_t kChromeFrameAboutVersion[] = - L"cf:about:version"; + L"gcf:about:version"; // This test launches chrome frame in full tab mode in IE by having IE navigate -// to cf:about:blank. It then looks for the chrome renderer window and posts +// to gcf:about:blank. It then looks for the chrome renderer window and posts // the WM_RBUTTONDOWN/WM_RBUTTONUP messages to it, which bring up the context // menu. This is followed by keyboard messages sent via SendInput to select // the About chrome frame menu option, which would then bring up a new window @@ -1583,7 +1608,7 @@ TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_BackForward) { } -const wchar_t kChromeFrameAboutBlankUrl[] = L"cf:about:blank"; +const wchar_t kChromeFrameAboutBlankUrl[] = L"gcf:about:blank"; TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ChromeFrameFocusTest) { chrome_frame_test::TimedMsgLoop loop; @@ -1797,6 +1822,80 @@ TEST_F(ChromeFrameTestWithWebServer, FLAKY_FullTabModeIE_BackForwardAnchor) { chrome_frame_test::CloseAllIEWindows(); } +// Full tab mode view source test +// Launch and navigate chrome frame and invoke view source functionality +TEST_F(ChromeFrameTestWithWebServer, FullTabModeIE_ViewSource) { + chrome_frame_test::TimedMsgLoop loop; + CComObjectStackEx<MockWebBrowserEventSink> mock; + CComObjectStackEx<MockWebBrowserEventSink> view_source_mock; + ::testing::InSequence sequence; // Everything in sequence + + // After navigation invoke view soruce action using IWebBrowser2::ExecWB + EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, + testing::StrCaseEq(kAnchorUrl)), + _, _, _, _, _)) + .WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnNavigateComplete2(_, _)) + .WillOnce(testing::Return()); + EXPECT_CALL(mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, + testing::StrCaseEq(kAnchorUrl)), + _, _, _, _, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return(S_OK)); + EXPECT_CALL(mock, OnNavigateComplete2(_, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return()); + + VARIANT empty = ScopedVariant::kEmptyVariant; + EXPECT_CALL(mock, OnLoad(testing::StrEq(kAnchorUrl))) + .WillOnce(testing::IgnoreResult(testing::InvokeWithoutArgs( + CreateFunctor(ReceivePointer(mock.web_browser2_), + &IWebBrowser2::ExecWB, + static_cast<OLECMDID>(IDM_VIEWSOURCE), + OLECMDEXECOPT_DONTPROMPTUSER, &empty, &empty)))); + + // Expect notification for view-source window, handle new window event + // and attach a new mock to the received web browser + std::wstring view_source_url; + view_source_url += UTF8ToWide(chrome::kViewSourceScheme); + view_source_url += L":"; + view_source_url += kAnchorUrl; + std::wstring url_in_new_window = kChromeProtocolPrefix; + url_in_new_window += view_source_url; + + EXPECT_CALL(mock, OnNewWindow3(_, _, _, _, + testing::StrCaseEq(url_in_new_window))); + EXPECT_CALL(mock, OnNewBrowserWindow(_, _)) + .WillOnce(testing::WithArgs<0>( + testing::Invoke(CreateFunctor(&view_source_mock, + &MockWebBrowserEventSink::Attach)))); + + // Expect navigations on the new mock + EXPECT_CALL(view_source_mock, OnBeforeNavigate2(_, + testing::Field(&VARIANT::bstrVal, + testing::StrCaseEq(url_in_new_window)), _, _, _, _, _)) + .Times(testing::AnyNumber()).WillOnce(testing::Return(S_OK)); + EXPECT_CALL(view_source_mock, OnNavigateComplete2(_, _)) + .WillOnce(testing::Return()); + EXPECT_CALL(view_source_mock, OnLoad(testing::StrEq(view_source_url))) + .WillOnce(testing::DoAll( + testing::InvokeWithoutArgs(CreateFunctor(&mock, + &MockWebBrowserEventSink::Uninitialize)), + testing::InvokeWithoutArgs(CreateFunctor(&view_source_mock, + &MockWebBrowserEventSink::Uninitialize)), + testing::IgnoreResult(testing::InvokeWithoutArgs( + &chrome_frame_test::CloseAllIEWindows)), + QUIT_LOOP_SOON(loop, 2))); + + HRESULT hr = mock.LaunchIEAndNavigate(kAnchorUrl); + ASSERT_HRESULT_SUCCEEDED(hr); + if (hr == S_FALSE) + return; + + ASSERT_TRUE(mock.web_browser2() != NULL); + loop.RunFor(kChromeFrameLongNavigationTimeoutInSeconds); + mock.Uninitialize(); + chrome_frame_test::CloseAllIEWindows(); +} + const wchar_t kChromeFrameFullTabModeXMLHttpRequestTestUrl[] = L"files/xmlhttprequest_test.html"; diff --git a/chrome_frame/test/data/cf_protocol.html b/chrome_frame/test/data/cf_protocol.html index 0036555..bee4055 100644 --- a/chrome_frame/test/data/cf_protocol.html +++ b/chrome_frame/test/data/cf_protocol.html @@ -15,6 +15,6 @@ </head>
<body onLoad="setTimeout(test, 100);">
<h2>Prepare to be redirected!</h2>
- <p>Redirects the same page to its 'cf:' version</p>
+ <p>Redirects the same page to its 'gcf:' version</p>
</body>
</html>
diff --git a/chrome_frame/test/data/chrome_frame_tester_helpers.js b/chrome_frame/test/data/chrome_frame_tester_helpers.js index f3ccd58..a6cc9c2 100644 --- a/chrome_frame/test/data/chrome_frame_tester_helpers.js +++ b/chrome_frame/test/data/chrome_frame_tester_helpers.js @@ -139,7 +139,7 @@ function isRunningInMSIE() { } function reloadUsingCFProtocol() { - var redirect_location = "cf:"; + var redirect_location = "gcf:"; redirect_location += window.location; window.location = redirect_location; } diff --git a/chrome_frame/test/data/navigate_out.html b/chrome_frame/test/data/navigate_out.html index 7b910b4..5f447c9 100644 --- a/chrome_frame/test/data/navigate_out.html +++ b/chrome_frame/test/data/navigate_out.html @@ -15,6 +15,6 @@ </head>
<body onLoad="setTimeout(test, 100);">
<h2>Prepare to be redirected!</h2>
- <p>Redirects the same page to its 'cf:' version and </p>
+ <p>Redirects the same page to its 'gcf:' version and </p>
</body>
</html>
diff --git a/chrome_frame/test/reliability/page_load_test.cc b/chrome_frame/test/reliability/page_load_test.cc index dd869e5..21fded4 100644 --- a/chrome_frame/test/reliability/page_load_test.cc +++ b/chrome_frame/test/reliability/page_load_test.cc @@ -133,9 +133,9 @@ class WebBrowserEventSinkImpl : public chrome_frame_test::WebBrowserEventSink { } virtual HRESULT Navigate(const std::wstring& navigate_url) { - if (StartsWith(navigate_url, L"cf:", true)) { + if (StartsWith(navigate_url, kChromeProtocolPrefix, true)) { is_chrome_frame_navigation_ = true; - url_ = navigate_url.substr(wcslen(L"cf:")); + url_ = navigate_url.substr(wcslen(kChromeProtocolPrefix)); } else { url_ = navigate_url; } @@ -349,7 +349,7 @@ class PageLoadTest : public testing::Test { // Every 3rd URL goes into the host browser. if (line_index % 3 != 0) { std::string actual_url; - actual_url = "cf:"; + actual_url = WideToUTF8(kChromeProtocolPrefix); actual_url += url_str; url_str = actual_url; } @@ -382,10 +382,12 @@ class PageLoadTest : public testing::Test { } SetConfigBool(kChromeFrameHeadlessMode, true); + SetConfigBool(kEnableGCFProtocol, true); } virtual void TearDown() { DeleteConfigValue(kChromeFrameHeadlessMode); + DeleteConfigValue(kEnableGCFProtocol); } FilePath ConstructSavedDebugLogPath(const FilePath& debug_log_path, diff --git a/chrome_frame/utils.cc b/chrome_frame/utils.cc index e6632f9..ae7a0d9 100644 --- a/chrome_frame/utils.cc +++ b/chrome_frame/utils.cc @@ -33,11 +33,12 @@ const wchar_t kContentAttribName[] = L"content"; const wchar_t kXUACompatValue[] = L"x-ua-compatible"; const wchar_t kBodyTag[] = L"body"; const wchar_t kChromeContentPrefix[] = L"chrome="; -const wchar_t kChromeProtocolPrefix[] = L"cf:"; +const wchar_t kChromeProtocolPrefix[] = L"gcf:"; static const wchar_t kChromeFrameConfigKey[] = L"Software\\Google\\ChromeFrame"; static const wchar_t kChromeFrameOptinUrlsKey[] = L"OptinUrls"; +static const wchar_t kEnableGCFProtocol[] = L"EnableGCFProtocol"; static const wchar_t kChromeFrameNPAPIKey[] = L"Software\\MozillaPlugins\\@google.com/ChromeFrame,version=1.0"; diff --git a/chrome_frame/utils.h b/chrome_frame/utils.h index e90a0d4..2cbb277 100644 --- a/chrome_frame/utils.h +++ b/chrome_frame/utils.h @@ -18,6 +18,8 @@ extern const wchar_t kChromeContentPrefix[]; extern const wchar_t kChromeProtocolPrefix[]; +extern const wchar_t kChromeFrameHeadlessMode[]; +extern const wchar_t kEnableGCFProtocol[]; // This function is very similar to the AtlRegisterTypeLib function except // that it takes a parameter that specifies whether to register the typelib @@ -314,8 +316,6 @@ STDMETHODIMP QueryInterfaceIfDelegateSupports(void* obj, REFIID iid, #define COM_INTERFACE_BLIND_DELEGATE() \ COM_INTERFACE_ENTRY_FUNC_BLIND(0, CheckOutgoingInterface<_ComMapClass>) -extern const wchar_t kChromeFrameHeadlessMode[]; - // Thread that enters STA and has a UI message loop. class STAThread : public base::Thread { public: |