diff --git a/include/capi/cef_load_handler_capi.h b/include/capi/cef_load_handler_capi.h index 9ef20c871..24e3c80d9 100644 --- a/include/capi/cef_load_handler_capi.h +++ b/include/capi/cef_load_handler_capi.h @@ -72,14 +72,17 @@ typedef struct _cef_load_handler_t { /// // Called when the browser begins loading a frame. The |frame| value will // never be NULL -- call the is_main() function to check if this frame is the - // main frame. Multiple frames may be loading at the same time. Sub-frames may - // start or continue loading after the main frame load has ended. This - // function will always be called for all frames irrespective of whether the - // request completes successfully. For notification of overall browser load - // status use OnLoadingStateChange instead. + // main frame. |transition_type| provides information about the source of the + // navigation and an accurate value is only available in the browser process. + // Multiple frames may be loading at the same time. Sub-frames may start or + // continue loading after the main frame load has ended. This function will + // always be called for all frames irrespective of whether the request + // completes successfully. For notification of overall browser load status use + // OnLoadingStateChange instead. /// void (CEF_CALLBACK *on_load_start)(struct _cef_load_handler_t* self, - struct _cef_browser_t* browser, struct _cef_frame_t* frame); + struct _cef_browser_t* browser, struct _cef_frame_t* frame, + cef_transition_type_t transition_type); /// // Called when the browser is done loading a frame. The |frame| value will diff --git a/include/cef_load_handler.h b/include/cef_load_handler.h index 29f7b740e..1494a844b 100644 --- a/include/cef_load_handler.h +++ b/include/cef_load_handler.h @@ -51,6 +51,7 @@ class CefLoadHandler : public virtual CefBase { public: typedef cef_errorcode_t ErrorCode; + typedef cef_transition_type_t TransitionType; /// // Called when the loading state has changed. This callback will be executed @@ -68,15 +69,18 @@ class CefLoadHandler : public virtual CefBase { /// // Called when the browser begins loading a frame. The |frame| value will // never be empty -- call the IsMain() method to check if this frame is the - // main frame. Multiple frames may be loading at the same time. Sub-frames may - // start or continue loading after the main frame load has ended. This method - // will always be called for all frames irrespective of whether the request + // main frame. |transition_type| provides information about the source of the + // navigation and an accurate value is only available in the browser process. + // Multiple frames may be loading at the same time. Sub-frames may start or + // continue loading after the main frame load has ended. This method will + // always be called for all frames irrespective of whether the request // completes successfully. For notification of overall browser load status use // OnLoadingStateChange instead. /// /*--cef()--*/ virtual void OnLoadStart(CefRefPtr browser, - CefRefPtr frame) {} + CefRefPtr frame, + TransitionType transition_type) {} /// // Called when the browser is done loading a frame. The |frame| value will diff --git a/libcef/browser/browser_host_impl.cc b/libcef/browser/browser_host_impl.cc index 14ff96a67..43d216a8d 100644 --- a/libcef/browser/browser_host_impl.cc +++ b/libcef/browser/browser_host_impl.cc @@ -2955,7 +2955,8 @@ void CefBrowserHostImpl::OnLoadStart(CefRefPtr frame, CefRefPtr handler = client_->GetLoadHandler(); if (handler.get()) { // Notify the handler that loading has started. - handler->OnLoadStart(this, frame); + handler->OnLoadStart(this, frame, + static_cast(transition_type)); } } } diff --git a/libcef/renderer/browser_impl.cc b/libcef/renderer/browser_impl.cc index c3e26d650..320c2d9d4 100644 --- a/libcef/renderer/browser_impl.cc +++ b/libcef/renderer/browser_impl.cc @@ -689,7 +689,7 @@ void CefBrowserImpl::OnLoadStart(blink::WebLocalFrame* frame) { CefRefPtr load_handler = handler->GetLoadHandler(); if (load_handler.get()) { CefRefPtr cef_frame = GetWebFrameImpl(frame); - load_handler->OnLoadStart(this, cef_frame.get()); + load_handler->OnLoadStart(this, cef_frame.get(), TT_EXPLICIT); } } } diff --git a/libcef_dll/cpptoc/load_handler_cpptoc.cc b/libcef_dll/cpptoc/load_handler_cpptoc.cc index b128f9c86..bd5ae4fce 100644 --- a/libcef_dll/cpptoc/load_handler_cpptoc.cc +++ b/libcef_dll/cpptoc/load_handler_cpptoc.cc @@ -41,7 +41,8 @@ void CEF_CALLBACK load_handler_on_loading_state_change( } void CEF_CALLBACK load_handler_on_load_start(struct _cef_load_handler_t* self, - cef_browser_t* browser, cef_frame_t* frame) { + cef_browser_t* browser, cef_frame_t* frame, + cef_transition_type_t transition_type) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING DCHECK(self); @@ -59,7 +60,8 @@ void CEF_CALLBACK load_handler_on_load_start(struct _cef_load_handler_t* self, // Execute CefLoadHandlerCppToC::Get(self)->OnLoadStart( CefBrowserCToCpp::Wrap(browser), - CefFrameCToCpp::Wrap(frame)); + CefFrameCToCpp::Wrap(frame), + transition_type); } void CEF_CALLBACK load_handler_on_load_end(struct _cef_load_handler_t* self, diff --git a/libcef_dll/ctocpp/load_handler_ctocpp.cc b/libcef_dll/ctocpp/load_handler_ctocpp.cc index 646a06d43..6389bc04a 100644 --- a/libcef_dll/ctocpp/load_handler_ctocpp.cc +++ b/libcef_dll/ctocpp/load_handler_ctocpp.cc @@ -39,7 +39,7 @@ void CefLoadHandlerCToCpp::OnLoadingStateChange(CefRefPtr browser, } void CefLoadHandlerCToCpp::OnLoadStart(CefRefPtr browser, - CefRefPtr frame) { + CefRefPtr frame, TransitionType transition_type) { cef_load_handler_t* _struct = GetStruct(); if (CEF_MEMBER_MISSING(_struct, on_load_start)) return; @@ -58,7 +58,8 @@ void CefLoadHandlerCToCpp::OnLoadStart(CefRefPtr browser, // Execute _struct->on_load_start(_struct, CefBrowserCppToC::Wrap(browser), - CefFrameCppToC::Wrap(frame)); + CefFrameCppToC::Wrap(frame), + transition_type); } void CefLoadHandlerCToCpp::OnLoadEnd(CefRefPtr browser, diff --git a/libcef_dll/ctocpp/load_handler_ctocpp.h b/libcef_dll/ctocpp/load_handler_ctocpp.h index 55db5ae3c..3a58492e3 100644 --- a/libcef_dll/ctocpp/load_handler_ctocpp.h +++ b/libcef_dll/ctocpp/load_handler_ctocpp.h @@ -33,8 +33,8 @@ class CefLoadHandlerCToCpp // CefLoadHandler methods. void OnLoadingStateChange(CefRefPtr browser, bool isLoading, bool canGoBack, bool canGoForward) override; - void OnLoadStart(CefRefPtr browser, - CefRefPtr frame) override; + void OnLoadStart(CefRefPtr browser, CefRefPtr frame, + TransitionType transition_type) override; void OnLoadEnd(CefRefPtr browser, CefRefPtr frame, int httpStatusCode) override; void OnLoadError(CefRefPtr browser, CefRefPtr frame, diff --git a/tests/unittests/frame_unittest.cc b/tests/unittests/frame_unittest.cc index 0f1959426..47115e5bb 100644 --- a/tests/unittests/frame_unittest.cc +++ b/tests/unittests/frame_unittest.cc @@ -355,7 +355,8 @@ class FrameNavRendererTest : public ClientAppRenderer::Delegate, } void OnLoadStart(CefRefPtr browser, - CefRefPtr frame) override { + CefRefPtr frame, + TransitionType transition_type) override { CreateExpectationsIfNecessary(); EXPECT_TRUE(expectations_->OnLoadStart(browser, frame)) << "nav = " << nav_; } @@ -522,7 +523,8 @@ class FrameNavTestHandler : public TestHandler { } void OnLoadStart(CefRefPtr browser, - CefRefPtr frame) override { + CefRefPtr frame, + TransitionType transition_type) override { EXPECT_TRUE(expectations_->OnLoadStart(browser, frame)) << "nav = " << nav_; } diff --git a/tests/unittests/navigation_unittest.cc b/tests/unittests/navigation_unittest.cc index 87662333a..f0f7e34bd 100644 --- a/tests/unittests/navigation_unittest.cc +++ b/tests/unittests/navigation_unittest.cc @@ -145,7 +145,8 @@ class HistoryNavRendererTest : public ClientAppRenderer::Delegate, } void OnLoadStart(CefRefPtr browser, - CefRefPtr frame) override { + CefRefPtr frame, + TransitionType transition_type) override { const NavListItem& item = kHNavList[nav_]; got_load_start_.yes(); @@ -153,6 +154,8 @@ class HistoryNavRendererTest : public ClientAppRenderer::Delegate, const std::string& url = frame->GetURL(); EXPECT_STREQ(item.target, url.c_str()); + EXPECT_EQ(TT_EXPLICIT, transition_type); + EXPECT_EQ(item.can_go_back, browser->CanGoBack()); EXPECT_EQ(item.can_go_forward, browser->CanGoForward()); } @@ -487,7 +490,8 @@ class HistoryNavTestHandler : public TestHandler { } void OnLoadStart(CefRefPtr browser, - CefRefPtr frame) override { + CefRefPtr frame, + TransitionType transition_type) override { if(browser->IsPopup() || !frame->IsMain()) return; @@ -495,6 +499,11 @@ class HistoryNavTestHandler : public TestHandler { got_load_start_[nav_].yes(); + if (item.action == NA_LOAD) + EXPECT_EQ(TT_EXPLICIT, transition_type); + else if (item.action == NA_BACK || item.action == NA_FORWARD) + EXPECT_EQ(TT_EXPLICIT | TT_FORWARD_BACK_FLAG, transition_type); + std::string url1 = browser->GetMainFrame()->GetURL(); std::string url2 = frame->GetURL(); if (url1 == item.target && url2 == item.target) @@ -793,10 +802,13 @@ class RedirectTestHandler : public TestHandler { } void OnLoadStart(CefRefPtr browser, - CefRefPtr frame) override { + CefRefPtr frame, + TransitionType transition_type) override { // Should only be called for the final loaded URL. std::string url = frame->GetURL(); + EXPECT_EQ(TT_EXPLICIT, transition_type); + if (url == kRNav4) { got_nav4_load_start_.yes(); } else { @@ -1198,7 +1210,8 @@ class OrderNavRendererTest : public ClientAppRenderer::Delegate, } void OnLoadStart(CefRefPtr browser, - CefRefPtr frame) override { + CefRefPtr frame, + TransitionType transition_type) override { EXPECT_TRUE(got_render_thread_created_); EXPECT_TRUE(got_webkit_initialized_); @@ -1409,10 +1422,13 @@ class OrderNavTestHandler : public TestHandler { } void OnLoadStart(CefRefPtr browser, - CefRefPtr frame) override { + CefRefPtr frame, + TransitionType transition_type) override { if (browser->IsPopup()) { + EXPECT_EQ(TT_LINK, transition_type); state_popup_.OnLoadStart(browser, frame); } else { + EXPECT_EQ(TT_EXPLICIT, transition_type); state_main_.OnLoadStart(browser, frame); } } @@ -1852,10 +1868,16 @@ class LoadNavTestHandler : public TestHandler { } void OnLoadStart(CefRefPtr browser, - CefRefPtr frame) override { + CefRefPtr frame, + TransitionType transition_type) override { EXPECT_GT(browser_id_current_, 0); EXPECT_EQ(browser_id_current_, browser->GetIdentifier()); + if (mode_ == LOAD || frame->GetURL() == kLoadNav1) + EXPECT_EQ(TT_EXPLICIT, transition_type); + else + EXPECT_EQ(TT_LINK, transition_type); + got_load_start_.yes(); } @@ -2133,7 +2155,8 @@ class PopupNavTestHandler : public TestHandler { } void OnLoadStart(CefRefPtr browser, - CefRefPtr frame) override { + CefRefPtr frame, + TransitionType transition_type) override { const std::string& url = frame->GetURL(); if (url == kPopupNavPageUrl) { EXPECT_FALSE(got_load_start_); @@ -2560,7 +2583,8 @@ class BrowseNavTestHandler : public TestHandler { } void OnLoadStart(CefRefPtr browser, - CefRefPtr frame) override { + CefRefPtr frame, + TransitionType transition_type) override { const std::string& url = frame->GetURL(); EXPECT_STREQ(kBrowseNavPageUrl, url.c_str()); EXPECT_EQ(GetBrowserId(), browser->GetIdentifier());