mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Don't call OnLoadEnd for same page navigations (issue #1852)
This commit is contained in:
@@ -44,6 +44,7 @@
|
||||
#include "chrome/browser/spellchecker/spellcheck_service.h"
|
||||
#include "chrome/browser/ui/prefs/prefs_tab_helper.h"
|
||||
#include "components/zoom/zoom_controller.h"
|
||||
#include "content/browser/frame_host/navigation_handle_impl.h"
|
||||
#include "content/browser/renderer_host/render_view_host_impl.h"
|
||||
#include "content/browser/gpu/compositor_util.h"
|
||||
#include "content/common/view_messages.h"
|
||||
@@ -53,6 +54,7 @@
|
||||
#include "content/public/browser/native_web_keyboard_event.h"
|
||||
#include "content/public/browser/navigation_controller.h"
|
||||
#include "content/public/browser/navigation_entry.h"
|
||||
#include "content/public/browser/navigation_handle.h"
|
||||
#include "content/public/browser/notification_details.h"
|
||||
#include "content/public/browser/notification_source.h"
|
||||
#include "content/public/browser/notification_types.h"
|
||||
@@ -61,6 +63,7 @@
|
||||
#include "content/public/browser/render_view_host.h"
|
||||
#include "content/public/browser/render_widget_host.h"
|
||||
#include "content/public/browser/resource_request_info.h"
|
||||
#include "net/base/net_errors.h"
|
||||
#include "third_party/WebKit/public/web/WebFindOptions.h"
|
||||
#include "ui/events/base_event_utils.h"
|
||||
|
||||
@@ -2499,36 +2502,51 @@ void CefBrowserHostImpl::RenderProcessGone(base::TerminationStatus status) {
|
||||
}
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::DidCommitProvisionalLoadForFrame(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& url,
|
||||
ui::PageTransition transition_type) {
|
||||
const bool is_main_frame = !render_frame_host->GetParent();
|
||||
void CefBrowserHostImpl::DidFinishNavigation(
|
||||
content::NavigationHandle* navigation_handle) {
|
||||
CHECK(navigation_handle->GetRenderFrameHost());
|
||||
|
||||
const net::Error error_code = navigation_handle->GetNetErrorCode();
|
||||
if (error_code == net::OK) {
|
||||
// The navigation has been committed.
|
||||
const bool is_main_frame = navigation_handle->IsInMainFrame();
|
||||
const GURL& url = navigation_handle->GetURL();
|
||||
|
||||
// This also updates the URL associated with the frame.
|
||||
CefRefPtr<CefFrame> frame = GetOrCreateFrame(
|
||||
render_frame_host->GetRoutingID(),
|
||||
navigation_handle->GetRenderFrameHost()->GetRoutingID(),
|
||||
CefFrameHostImpl::kUnspecifiedFrameId,
|
||||
is_main_frame,
|
||||
base::string16(),
|
||||
url);
|
||||
OnLoadStart(frame, url, transition_type);
|
||||
is_main_frame, base::string16(), url);
|
||||
|
||||
// Don't call OnLoadStart for same page navigations (fragments,
|
||||
// history state).
|
||||
if (!navigation_handle->IsSamePage())
|
||||
OnLoadStart(frame, navigation_handle->GetPageTransition());
|
||||
|
||||
if (is_main_frame)
|
||||
OnAddressChange(frame, url);
|
||||
} else {
|
||||
// The navigation failed before commit. Originates from
|
||||
// RenderFrameHostImpl::OnDidFailProvisionalLoadWithError.
|
||||
CefRefPtr<CefFrame> frame = GetOrCreateFrame(
|
||||
navigation_handle->GetRenderFrameHost()->GetRoutingID(),
|
||||
CefFrameHostImpl::kUnspecifiedFrameId,
|
||||
navigation_handle->IsInMainFrame(), base::string16(), GURL());
|
||||
|
||||
// OnLoadStart/OnLoadEnd will not be called.
|
||||
OnLoadError(frame, navigation_handle->GetURL(), error_code);
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::DidFailProvisionalLoad(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& validated_url,
|
||||
int error_code,
|
||||
const base::string16& error_description,
|
||||
bool was_ignored_by_handler) {
|
||||
const bool is_main_frame = !render_frame_host->GetParent();
|
||||
CefRefPtr<CefFrame> frame = GetOrCreateFrame(
|
||||
render_frame_host->GetRoutingID(),
|
||||
CefFrameHostImpl::kUnspecifiedFrameId,
|
||||
is_main_frame,
|
||||
base::string16(),
|
||||
GURL());
|
||||
OnLoadError(frame, validated_url, error_code, error_description);
|
||||
if (!web_contents())
|
||||
return;
|
||||
|
||||
CefBrowserContext* context =
|
||||
static_cast<CefBrowserContext*>(web_contents()->GetBrowserContext());
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
context->AddVisitedURLs(static_cast<content::NavigationHandleImpl*>(
|
||||
navigation_handle)->redirect_chain());
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::DocumentAvailableInMainFrame() {
|
||||
@@ -2542,6 +2560,8 @@ void CefBrowserHostImpl::DidFailLoad(
|
||||
int error_code,
|
||||
const base::string16& error_description,
|
||||
bool was_ignored_by_handler) {
|
||||
// The navigation failed after commit. OnLoadStart was called so we also call
|
||||
// OnLoadEnd.
|
||||
const bool is_main_frame = !render_frame_host->GetParent();
|
||||
CefRefPtr<CefFrame> frame = GetOrCreateFrame(
|
||||
render_frame_host->GetRoutingID(),
|
||||
@@ -2549,7 +2569,7 @@ void CefBrowserHostImpl::DidFailLoad(
|
||||
is_main_frame,
|
||||
base::string16(),
|
||||
validated_url);
|
||||
OnLoadError(frame, validated_url, error_code, error_description);
|
||||
OnLoadError(frame, validated_url, error_code);
|
||||
OnLoadEnd(frame, validated_url, error_code);
|
||||
}
|
||||
|
||||
@@ -2570,21 +2590,6 @@ void CefBrowserHostImpl::FrameDeleted(
|
||||
focused_frame_id_ = CefFrameHostImpl::kInvalidFrameId;
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::DidNavigateAnyFrame(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const content::LoadCommittedDetails& details,
|
||||
const content::FrameNavigateParams& params) {
|
||||
if (!web_contents())
|
||||
return;
|
||||
|
||||
CefBrowserContext* context =
|
||||
static_cast<CefBrowserContext*>(web_contents()->GetBrowserContext());
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
context->AddVisitedURLs(params.redirects);
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::TitleWasSet(content::NavigationEntry* entry,
|
||||
bool explicit_set) {
|
||||
// |entry| may be NULL if a popup is created via window.open and never
|
||||
@@ -3034,7 +3039,6 @@ void CefBrowserHostImpl::OnAddressChange(CefRefPtr<CefFrame> frame,
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::OnLoadStart(CefRefPtr<CefFrame> frame,
|
||||
const GURL& url,
|
||||
ui::PageTransition transition_type) {
|
||||
if (client_.get()) {
|
||||
CefRefPtr<CefLoadHandler> handler = client_->GetLoadHandler();
|
||||
@@ -3048,8 +3052,7 @@ void CefBrowserHostImpl::OnLoadStart(CefRefPtr<CefFrame> frame,
|
||||
|
||||
void CefBrowserHostImpl::OnLoadError(CefRefPtr<CefFrame> frame,
|
||||
const GURL& url,
|
||||
int error_code,
|
||||
const base::string16& error_description) {
|
||||
int error_code) {
|
||||
if (client_.get()) {
|
||||
CefRefPtr<CefLoadHandler> handler = client_->GetLoadHandler();
|
||||
if (handler.get()) {
|
||||
@@ -3057,7 +3060,7 @@ void CefBrowserHostImpl::OnLoadError(CefRefPtr<CefFrame> frame,
|
||||
// Notify the handler that loading has failed.
|
||||
handler->OnLoadError(this, frame,
|
||||
static_cast<cef_errorcode_t>(error_code),
|
||||
CefString(error_description),
|
||||
net::ErrorToShortString(error_code),
|
||||
url.spec());
|
||||
frame_destruction_pending_ = false;
|
||||
}
|
||||
|
@@ -448,38 +448,21 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
// content::WebContentsObserver methods.
|
||||
using content::WebContentsObserver::BeforeUnloadFired;
|
||||
using content::WebContentsObserver::WasHidden;
|
||||
void RenderFrameCreated(
|
||||
content::RenderFrameHost* render_frame_host) override;
|
||||
void RenderFrameDeleted(
|
||||
content::RenderFrameHost* render_frame_host) override;
|
||||
void RenderViewCreated(
|
||||
content::RenderViewHost* render_view_host) override;
|
||||
void RenderViewDeleted(
|
||||
content::RenderViewHost* render_view_host) override;
|
||||
void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
|
||||
void RenderFrameDeleted(content::RenderFrameHost* render_frame_host) override;
|
||||
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
|
||||
void RenderViewDeleted(content::RenderViewHost* render_view_host) override;
|
||||
void RenderViewReady() override;
|
||||
void RenderProcessGone(base::TerminationStatus status) override;
|
||||
void DidCommitProvisionalLoadForFrame(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& url,
|
||||
ui::PageTransition transition_type) override;
|
||||
void DidFailProvisionalLoad(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const GURL& validated_url,
|
||||
int error_code,
|
||||
const base::string16& error_description,
|
||||
bool was_ignored_by_handler) override;
|
||||
void DidFinishNavigation(
|
||||
content::NavigationHandle* navigation_handle) override;
|
||||
void DocumentAvailableInMainFrame() override;
|
||||
void DidFailLoad(content::RenderFrameHost* render_frame_host,
|
||||
const GURL& validated_url,
|
||||
int error_code,
|
||||
const base::string16& error_description,
|
||||
bool was_ignored_by_handler) override;
|
||||
void FrameDeleted(
|
||||
content::RenderFrameHost* render_frame_host) override;
|
||||
void DidNavigateAnyFrame(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
const content::LoadCommittedDetails& details,
|
||||
const content::FrameNavigateParams& params) override;
|
||||
void FrameDeleted(content::RenderFrameHost* render_frame_host) override;
|
||||
void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override;
|
||||
void PluginCrashed(const base::FilePath& plugin_path,
|
||||
base::ProcessId plugin_pid) override;
|
||||
@@ -554,12 +537,10 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
void OnAddressChange(CefRefPtr<CefFrame> frame,
|
||||
const GURL& url);
|
||||
void OnLoadStart(CefRefPtr<CefFrame> frame,
|
||||
const GURL& url,
|
||||
ui::PageTransition transition_type);
|
||||
void OnLoadError(CefRefPtr<CefFrame> frame,
|
||||
const GURL& url,
|
||||
int error_code,
|
||||
const base::string16& error_description);
|
||||
int error_code);
|
||||
void OnLoadEnd(CefRefPtr<CefFrame> frame,
|
||||
const GURL& url,
|
||||
int http_status_code);
|
||||
|
@@ -327,4 +327,11 @@ patches = [
|
||||
'name': 'views_menu_2102',
|
||||
'path': '../',
|
||||
},
|
||||
{
|
||||
# Expose RFH via NavigationHandle for retrieval in DidFinishNavigation on
|
||||
# network error.
|
||||
# https://groups.google.com/a/chromium.org/d/msg/chromium-dev/6iAQPx_hwh8/gaTR5f1GAQAJ
|
||||
'name': 'navigation_handle',
|
||||
'path': '../',
|
||||
},
|
||||
]
|
||||
|
42
patch/patches/navigation_handle.patch
Normal file
42
patch/patches/navigation_handle.patch
Normal file
@@ -0,0 +1,42 @@
|
||||
diff --git content/browser/frame_host/navigation_handle_impl.cc content/browser/frame_host/navigation_handle_impl.cc
|
||||
index 30536bd..6fdb9a3 100644
|
||||
--- content/browser/frame_host/navigation_handle_impl.cc
|
||||
+++ content/browser/frame_host/navigation_handle_impl.cc
|
||||
@@ -223,12 +223,6 @@ net::Error NavigationHandleImpl::GetNetErrorCode() {
|
||||
}
|
||||
|
||||
RenderFrameHostImpl* NavigationHandleImpl::GetRenderFrameHost() {
|
||||
- // TODO(mkwst): Change this to check against 'READY_TO_COMMIT' once
|
||||
- // ReadyToCommitNavigation is available whether or not PlzNavigate is
|
||||
- // enabled. https://crbug.com/621856
|
||||
- CHECK_GE(state_, WILL_PROCESS_RESPONSE)
|
||||
- << "This accessor should only be called after a response has been "
|
||||
- "delivered for processing.";
|
||||
return render_frame_host_;
|
||||
}
|
||||
|
||||
diff --git content/browser/frame_host/navigation_handle_impl.h content/browser/frame_host/navigation_handle_impl.h
|
||||
index 19b6871..6e85c69 100644
|
||||
--- content/browser/frame_host/navigation_handle_impl.h
|
||||
+++ content/browser/frame_host/navigation_handle_impl.h
|
||||
@@ -300,6 +300,8 @@ class CONTENT_EXPORT NavigationHandleImpl : public NavigationHandle {
|
||||
searchable_form_encoding_ = encoding;
|
||||
}
|
||||
|
||||
+ const std::vector<GURL>& redirect_chain() const { return redirect_chain_; }
|
||||
+
|
||||
private:
|
||||
friend class NavigationHandleImplTest;
|
||||
|
||||
diff --git content/browser/frame_host/render_frame_host_impl.cc content/browser/frame_host/render_frame_host_impl.cc
|
||||
index e496ce3..de019a8 100644
|
||||
--- content/browser/frame_host/render_frame_host_impl.cc
|
||||
+++ content/browser/frame_host/render_frame_host_impl.cc
|
||||
@@ -1139,6 +1139,7 @@ void RenderFrameHostImpl::OnDidFailProvisionalLoadWithError(
|
||||
if (navigation_handle_) {
|
||||
navigation_handle_->set_net_error_code(
|
||||
static_cast<net::Error>(params.error_code));
|
||||
+ navigation_handle_->set_render_frame_host(this);
|
||||
}
|
||||
|
||||
frame_tree_node_->navigator()->DidFailProvisionalLoadWithError(this, params);
|
@@ -1058,6 +1058,8 @@ class MultiQueryManager : public CefMessageRouterBrowserSide::Handler {
|
||||
|
||||
virtual ~MultiQueryManager() {}
|
||||
|
||||
std::string label() const { return label_; }
|
||||
|
||||
void AddObserver(Observer* observer) {
|
||||
EXPECT_FALSE(running_);
|
||||
observer_set_.insert(observer);
|
||||
@@ -2274,15 +2276,12 @@ class MultiQueryManagerMap :
|
||||
MultiQueryManager* CreateManager(const std::string& url, bool synchronous) {
|
||||
EXPECT_FALSE(finalized_);
|
||||
|
||||
// The sub-frame resource should not already exist.
|
||||
URLManagerMap::const_iterator it = manager_map_.find(url);
|
||||
EXPECT_EQ(it, manager_map_.end());
|
||||
|
||||
MultiQueryManager* manager =
|
||||
new MultiQueryManager(url, synchronous,
|
||||
static_cast<int>(manager_map_.size()) * 1000);
|
||||
manager->AddObserver(this);
|
||||
manager_map_.insert(std::make_pair(url, manager));
|
||||
all_managers_.push_back(manager);
|
||||
pending_managers_.push_back(manager);
|
||||
|
||||
return manager;
|
||||
}
|
||||
@@ -2298,11 +2297,10 @@ class MultiQueryManagerMap :
|
||||
|
||||
std::string html = "<html><body>\n";
|
||||
|
||||
URLManagerMap::const_iterator it = manager_map_.begin();
|
||||
for (; it != manager_map_.end(); ++it) {
|
||||
const std::string& name = GetNameForURL(it->first);
|
||||
html += "<iframe id=\"" + name + "\" src=\"" + it->first +
|
||||
"\"></iframe>\n";
|
||||
for (size_t i = 0; i < all_managers_.size(); ++i) {
|
||||
const std::string& url = all_managers_[i]->label();
|
||||
const std::string& name = GetNameForURL(url);
|
||||
html += "<iframe id=\"" + name + "\" src=\"" + url + "\"></iframe>\n";
|
||||
}
|
||||
|
||||
html += "</body></html>";
|
||||
@@ -2347,7 +2345,7 @@ class MultiQueryManagerMap :
|
||||
}
|
||||
|
||||
void OnManualQueriesCompleted(MultiQueryManager* manager) override {
|
||||
const int size = static_cast<int>(manager_map_.size());
|
||||
const int size = static_cast<int>(all_managers_.size());
|
||||
EXPECT_LT(manual_complete_count_, size);
|
||||
if (++manual_complete_count_ == size) {
|
||||
running_ = false;
|
||||
@@ -2367,7 +2365,7 @@ class MultiQueryManagerMap :
|
||||
}
|
||||
|
||||
void OnAllQueriesCompleted(MultiQueryManager* manager) override {
|
||||
const int size = static_cast<int>(manager_map_.size());
|
||||
const int size = static_cast<int>(all_managers_.size());
|
||||
EXPECT_LT(total_complete_count_, size);
|
||||
if (++total_complete_count_ == size) {
|
||||
running_ = false;
|
||||
@@ -2389,9 +2387,8 @@ class MultiQueryManagerMap :
|
||||
bool AllComplete() const {
|
||||
EXPECT_TRUE(finalized_);
|
||||
|
||||
URLManagerMap::const_iterator it = manager_map_.begin();
|
||||
for (; it != manager_map_.end(); ++it) {
|
||||
if (!it->second->IsAllComplete())
|
||||
for (size_t i = 0; i < all_managers_.size(); ++i) {
|
||||
if (!all_managers_[i]->IsAllComplete())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -2399,55 +2396,84 @@ class MultiQueryManagerMap :
|
||||
|
||||
void AssertAllComplete() const {
|
||||
EXPECT_TRUE(finalized_);
|
||||
EXPECT_TRUE(pending_managers_.empty());
|
||||
EXPECT_FALSE(running_);
|
||||
|
||||
URLManagerMap::const_iterator it = manager_map_.begin();
|
||||
for (; it != manager_map_.end(); ++it)
|
||||
it->second->AssertAllComplete();
|
||||
for (size_t i = 0; i < all_managers_.size(); ++i) {
|
||||
all_managers_[i]->AssertAllComplete();
|
||||
}
|
||||
}
|
||||
|
||||
bool HasAutoQueries() const {
|
||||
if (manager_map_.empty())
|
||||
return false;
|
||||
|
||||
URLManagerMap::const_iterator it = manager_map_.begin();
|
||||
for (; it != manager_map_.end(); ++it) {
|
||||
if (it->second->HasAutoQueries())
|
||||
for (size_t i = 0; i < all_managers_.size(); ++i) {
|
||||
if (all_managers_[i]->HasAutoQueries())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnLoadStart(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame) {
|
||||
if (pending_managers_.empty())
|
||||
return;
|
||||
|
||||
const std::string& expected_url = frame->GetURL();
|
||||
MultiQueryManager* next_manager = nullptr;
|
||||
|
||||
// Find the pending manager that matches the expected URL.
|
||||
ManagerList::iterator it = pending_managers_.begin();
|
||||
for (; it != pending_managers_.end(); ++it) {
|
||||
if ((*it)->label() == expected_url) {
|
||||
next_manager = *it;
|
||||
pending_managers_.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_TRUE(next_manager);
|
||||
|
||||
const int browser_id = browser->GetIdentifier();
|
||||
// Always use the same ID for the main frame.
|
||||
const int64 frame_id = frame->IsMain() ? -1 : frame->GetIdentifier();
|
||||
|
||||
const std::pair<int, int64>& id = std::make_pair(browser_id, frame_id);
|
||||
|
||||
// Remove the currently active manager, if any.
|
||||
ManagerMap::iterator it2 = manager_map_.find(id);
|
||||
if (it2 != manager_map_.end())
|
||||
manager_map_.erase(it2);
|
||||
|
||||
// Add the next manager to the active map.
|
||||
manager_map_.insert(std::make_pair(id, next_manager));
|
||||
}
|
||||
|
||||
MultiQueryManager* GetManager(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame) const {
|
||||
const std::string& url = frame->GetURL();
|
||||
URLManagerMap::const_iterator it = manager_map_.find(url);
|
||||
EXPECT_NE(it, manager_map_.end());
|
||||
const int browser_id = browser->GetIdentifier();
|
||||
// Always use the same ID for the main frame.
|
||||
const int64 frame_id = frame->IsMain() ? -1 : frame->GetIdentifier();
|
||||
|
||||
// Find the manager in the active map.
|
||||
ManagerMap::const_iterator it =
|
||||
manager_map_.find(std::make_pair(browser_id, frame_id));
|
||||
EXPECT_NE(it, manager_map_.end()) <<
|
||||
"browser_id = " << browser_id << ", frame_id = " << frame_id;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void RemoveAllManagers() {
|
||||
if (manager_map_.empty())
|
||||
EXPECT_TRUE(pending_managers_.empty());
|
||||
if (all_managers_.empty())
|
||||
return;
|
||||
|
||||
URLManagerMap::const_iterator it = manager_map_.begin();
|
||||
for (; it != manager_map_.end(); ++it)
|
||||
delete it->second;
|
||||
for (size_t i = 0; i < all_managers_.size(); ++i) {
|
||||
delete all_managers_[i];
|
||||
}
|
||||
all_managers_.clear();
|
||||
manager_map_.clear();
|
||||
}
|
||||
|
||||
std::string GetURLForManager(MultiQueryManager* manager) const {
|
||||
if (!manager_map_.empty()) {
|
||||
URLManagerMap::const_iterator it = manager_map_.begin();
|
||||
for (; it != manager_map_.end(); ++it) {
|
||||
if (it->second == manager)
|
||||
return it->first;
|
||||
}
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
static std::string GetNameForURL(const std::string& url) {
|
||||
// Extract the file name without extension.
|
||||
int pos1 = static_cast<int>(url.rfind("/"));
|
||||
@@ -2457,9 +2483,16 @@ class MultiQueryManagerMap :
|
||||
}
|
||||
|
||||
private:
|
||||
// Map of page URL to MultiQueryManager instance.
|
||||
typedef std::map<std::string, MultiQueryManager*> URLManagerMap;
|
||||
URLManagerMap manager_map_;
|
||||
typedef std::vector<MultiQueryManager*> ManagerList;
|
||||
// Map of (browser ID, frame ID) to manager.
|
||||
typedef std::map<std::pair<int, int64>, MultiQueryManager*> ManagerMap;
|
||||
|
||||
// All managers that have been created.
|
||||
ManagerList all_managers_;
|
||||
// Managers that have not yet associated with a frame.
|
||||
ManagerList pending_managers_;
|
||||
// Managers that are currently active.
|
||||
ManagerMap manager_map_;
|
||||
|
||||
typedef std::set<Observer*> ObserverSet;
|
||||
ObserverSet observer_set_;
|
||||
@@ -2501,6 +2534,14 @@ class MultiQueryMultiFrameTestHandler :
|
||||
return manager_map_.GetMainHTML();
|
||||
}
|
||||
|
||||
void OnLoadStart(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
TransitionType transition_type) override {
|
||||
AssertMainBrowser(browser);
|
||||
if (!frame->IsMain())
|
||||
manager_map_.OnLoadStart(browser, frame);
|
||||
}
|
||||
|
||||
void OnNotify(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
const std::string& message) override {
|
||||
@@ -2637,6 +2678,12 @@ class MultiQueryMultiLoadTestHandler :
|
||||
manager_map_.AddObserver(this);
|
||||
}
|
||||
|
||||
void OnLoadStart(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
TransitionType transition_type) override {
|
||||
manager_map_.OnLoadStart(browser, frame);
|
||||
}
|
||||
|
||||
void OnNotify(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
const std::string& message) override {
|
||||
@@ -2797,7 +2844,7 @@ class MultiQueryMultiNavigateTestHandler : public MultiQueryMultiLoadTestHandler
|
||||
}
|
||||
|
||||
void OnManualQueriesCompleted(MultiQueryManager* manager) override {
|
||||
const std::string& url = manager_map_.GetURLForManager(manager);
|
||||
const std::string& url = manager->label();
|
||||
if (url == url1_) // 2. Load the 2nd url.
|
||||
GetBrowser()->GetMainFrame()->LoadURL(url2_);
|
||||
else if (url == url2_) // 3. Load the 3rd url.
|
||||
|
@@ -2325,6 +2325,23 @@ class PopupNavTestHandler : public TestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
void OnLoadError(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
ErrorCode errorCode,
|
||||
const CefString& errorText,
|
||||
const CefString& failedUrl) override {
|
||||
if (failedUrl == kPopupNavPageUrl) {
|
||||
EXPECT_FALSE(got_load_error_);
|
||||
got_load_error_.yes();
|
||||
} else if (failedUrl == kPopupNavPopupUrl) {
|
||||
EXPECT_FALSE(got_popup_load_error_);
|
||||
got_popup_load_error_.yes();
|
||||
} else if (failedUrl == kPopupNavPopupUrl2) {
|
||||
EXPECT_FALSE(got_popup_load_error2_);
|
||||
got_popup_load_error2_.yes();
|
||||
}
|
||||
}
|
||||
|
||||
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int httpStatusCode) override {
|
||||
@@ -2370,22 +2387,29 @@ class PopupNavTestHandler : public TestHandler {
|
||||
private:
|
||||
void DestroyTest() override {
|
||||
EXPECT_TRUE(got_load_start_);
|
||||
EXPECT_FALSE(got_load_error_);
|
||||
EXPECT_TRUE(got_load_end_);
|
||||
EXPECT_TRUE(got_on_before_popup_);
|
||||
if (mode_ == ALLOW) {
|
||||
EXPECT_TRUE(got_popup_load_start_);
|
||||
EXPECT_FALSE(got_popup_load_error_);
|
||||
EXPECT_TRUE(got_popup_load_end_);
|
||||
EXPECT_FALSE(got_popup_load_start2_);
|
||||
EXPECT_FALSE(got_popup_load_error2_);
|
||||
EXPECT_FALSE(got_popup_load_end2_);
|
||||
} else if (mode_ == DENY) {
|
||||
EXPECT_FALSE(got_popup_load_start_);
|
||||
EXPECT_FALSE(got_popup_load_error_);
|
||||
EXPECT_FALSE(got_popup_load_end_);
|
||||
EXPECT_FALSE(got_popup_load_start2_);
|
||||
EXPECT_FALSE(got_popup_load_error2_);
|
||||
EXPECT_FALSE(got_popup_load_end2_);
|
||||
} else if (mode_ == NAVIGATE_AFTER_CREATION) {
|
||||
EXPECT_FALSE(got_popup_load_start_);
|
||||
EXPECT_TRUE(got_popup_load_error_);
|
||||
EXPECT_FALSE(got_popup_load_end_);
|
||||
EXPECT_TRUE(got_popup_load_start2_);
|
||||
EXPECT_FALSE(got_popup_load_error2_);
|
||||
EXPECT_TRUE(got_popup_load_end2_);
|
||||
}
|
||||
|
||||
@@ -2396,10 +2420,13 @@ class PopupNavTestHandler : public TestHandler {
|
||||
|
||||
TrackCallback got_on_before_popup_;
|
||||
TrackCallback got_load_start_;
|
||||
TrackCallback got_load_error_;
|
||||
TrackCallback got_load_end_;
|
||||
TrackCallback got_popup_load_start_;
|
||||
TrackCallback got_popup_load_error_;
|
||||
TrackCallback got_popup_load_end_;
|
||||
TrackCallback got_popup_load_start2_;
|
||||
TrackCallback got_popup_load_error2_;
|
||||
TrackCallback got_popup_load_end2_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(PopupNavTestHandler);
|
||||
@@ -2865,6 +2892,671 @@ TEST(NavigationTest, BrowseDeny) {
|
||||
ReleaseAndWaitForDestructor(handler);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const char kSameNavPageUrl[] = "http://tests-samenav/nav.html";
|
||||
|
||||
// Browser side.
|
||||
class SameNavTestHandler : public TestHandler {
|
||||
public:
|
||||
SameNavTestHandler()
|
||||
: destroyed_(false),
|
||||
step_(0) {}
|
||||
|
||||
void RunTest() override {
|
||||
AddResource(kSameNavPageUrl, "<html>Test</html>", "text/html");
|
||||
|
||||
// Create the browser.
|
||||
expected_url_ = kSameNavPageUrl;
|
||||
CreateBrowser(kSameNavPageUrl);
|
||||
|
||||
// Time out the test after a reasonable period of time.
|
||||
SetTestTimeout();
|
||||
}
|
||||
|
||||
bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
bool is_redirect) override {
|
||||
const std::string& url = request->GetURL();
|
||||
EXPECT_STREQ(expected_url_.c_str(), url.c_str());
|
||||
EXPECT_EQ(GetBrowserId(), browser->GetIdentifier());
|
||||
EXPECT_TRUE(frame->IsMain());
|
||||
|
||||
got_before_browse_.yes();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnLoadStart(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
TransitionType transition_type) override {
|
||||
const std::string& url = frame->GetURL();
|
||||
EXPECT_STREQ(expected_url_.c_str(), url.c_str());
|
||||
EXPECT_EQ(GetBrowserId(), browser->GetIdentifier());
|
||||
EXPECT_TRUE(frame->IsMain());
|
||||
|
||||
got_load_start_.yes();
|
||||
}
|
||||
|
||||
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int httpStatusCode) override {
|
||||
const std::string& url = frame->GetURL();
|
||||
EXPECT_STREQ(expected_url_.c_str(), url.c_str());
|
||||
EXPECT_EQ(GetBrowserId(), browser->GetIdentifier());
|
||||
EXPECT_TRUE(frame->IsMain());
|
||||
|
||||
got_load_end_.yes();
|
||||
ContinueTestIfDone();
|
||||
}
|
||||
|
||||
void OnLoadError(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
ErrorCode errorCode,
|
||||
const CefString& errorText,
|
||||
const CefString& failedUrl) override {
|
||||
got_load_error_.yes();
|
||||
}
|
||||
|
||||
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
||||
bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) override {
|
||||
const std::string& url = browser->GetMainFrame()->GetURL();
|
||||
EXPECT_EQ(GetBrowserId(), browser->GetIdentifier());
|
||||
|
||||
if (isLoading) {
|
||||
// Verify the previous URL.
|
||||
if (step_ == 0)
|
||||
EXPECT_TRUE(url.empty());
|
||||
else
|
||||
EXPECT_STREQ(kSameNavPageUrl, url.c_str());
|
||||
|
||||
got_loading_state_changed_start_.yes();
|
||||
} else {
|
||||
EXPECT_STREQ(expected_url_.c_str(), url.c_str());
|
||||
|
||||
got_loading_state_changed_end_.yes();
|
||||
ContinueTestIfDone();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void ContinueTestIfDone() {
|
||||
if (step_ == 0) {
|
||||
// First navigation should trigger all callbacks except OnLoadError.
|
||||
if (got_loading_state_changed_end_ && got_load_end_) {
|
||||
EXPECT_TRUE(got_before_browse_);
|
||||
EXPECT_TRUE(got_loading_state_changed_start_);
|
||||
EXPECT_TRUE(got_load_start_);
|
||||
EXPECT_FALSE(got_load_error_);
|
||||
|
||||
got_before_browse_.reset();
|
||||
got_loading_state_changed_start_.reset();
|
||||
got_loading_state_changed_end_.reset();
|
||||
got_load_start_.reset();
|
||||
got_load_end_.reset();
|
||||
|
||||
step_++;
|
||||
expected_url_ = kSameNavPageUrl + std::string("#fragment");
|
||||
GetBrowser()->GetMainFrame()->LoadURL(expected_url_);
|
||||
}
|
||||
} else if (step_ == 1) {
|
||||
step_++;
|
||||
DestroyTest();
|
||||
} else {
|
||||
EXPECT_TRUE(false); // Not reached.
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyTest() override {
|
||||
if (destroyed_)
|
||||
return;
|
||||
destroyed_ = true;
|
||||
|
||||
EXPECT_EQ(2, step_);
|
||||
|
||||
// Second (fragment) navigation should only trigger OnLoadingStateChange.
|
||||
EXPECT_FALSE(got_before_browse_);
|
||||
EXPECT_TRUE(got_loading_state_changed_start_);
|
||||
EXPECT_TRUE(got_loading_state_changed_end_);
|
||||
EXPECT_FALSE(got_load_start_);
|
||||
EXPECT_FALSE(got_load_end_);
|
||||
EXPECT_FALSE(got_load_error_);
|
||||
|
||||
TestHandler::DestroyTest();
|
||||
}
|
||||
|
||||
bool destroyed_;
|
||||
int step_;
|
||||
std::string expected_url_;
|
||||
|
||||
TrackCallback got_before_browse_;
|
||||
TrackCallback got_load_start_;
|
||||
TrackCallback got_load_end_;
|
||||
TrackCallback got_load_error_;
|
||||
TrackCallback got_loading_state_changed_start_;
|
||||
TrackCallback got_loading_state_changed_end_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(SameNavTestHandler);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// Test that same page navigation does not call OnLoadStart/OnLoadEnd.
|
||||
TEST(NavigationTest, SamePage) {
|
||||
CefRefPtr<SameNavTestHandler> handler = new SameNavTestHandler();
|
||||
handler->ExecuteTest();
|
||||
ReleaseAndWaitForDestructor(handler);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const char kCancelPageUrl[] = "http://tests-cancelnav/nav.html";
|
||||
|
||||
// A scheme handler that never starts sending data.
|
||||
class UnstartedSchemeHandler : public CefResourceHandler {
|
||||
public:
|
||||
UnstartedSchemeHandler() {}
|
||||
|
||||
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
callback->Continue();
|
||||
return true;
|
||||
}
|
||||
|
||||
void GetResponseHeaders(CefRefPtr<CefResponse> response,
|
||||
int64& response_length,
|
||||
CefString& redirectUrl) override {
|
||||
response->SetStatus(200);
|
||||
response->SetMimeType("text/html");
|
||||
response_length = 100;
|
||||
}
|
||||
|
||||
void Cancel() override {
|
||||
callback_ = nullptr;
|
||||
}
|
||||
|
||||
bool ReadResponse(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
callback_ = callback;
|
||||
|
||||
// Pretend that we'll provide the data later.
|
||||
bytes_read = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
CefRefPtr<CefCallback> callback_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(UnstartedSchemeHandler);
|
||||
};
|
||||
|
||||
// Browser side.
|
||||
class CancelBeforeNavTestHandler : public TestHandler {
|
||||
public:
|
||||
CancelBeforeNavTestHandler()
|
||||
: destroyed_(false) {}
|
||||
|
||||
void RunTest() override {
|
||||
// Create the browser.
|
||||
CreateBrowser(kCancelPageUrl);
|
||||
|
||||
// Time out the test after a reasonable period of time.
|
||||
SetTestTimeout();
|
||||
}
|
||||
|
||||
bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
bool is_redirect) override {
|
||||
EXPECT_TRUE(got_loading_state_changed_start_);
|
||||
EXPECT_FALSE(got_before_browse_);
|
||||
EXPECT_FALSE(got_get_resource_handler_);
|
||||
EXPECT_FALSE(got_load_start_);
|
||||
EXPECT_FALSE(got_cancel_load_);
|
||||
EXPECT_FALSE(got_load_error_);
|
||||
EXPECT_FALSE(got_load_end_);
|
||||
EXPECT_FALSE(got_loading_state_changed_end_);
|
||||
|
||||
const std::string& url = request->GetURL();
|
||||
EXPECT_STREQ(kCancelPageUrl, url.c_str());
|
||||
EXPECT_EQ(GetBrowserId(), browser->GetIdentifier());
|
||||
EXPECT_TRUE(frame->IsMain());
|
||||
|
||||
got_before_browse_.yes();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> GetResourceHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request) override {
|
||||
EXPECT_TRUE(got_loading_state_changed_start_);
|
||||
EXPECT_TRUE(got_before_browse_);
|
||||
EXPECT_FALSE(got_get_resource_handler_);
|
||||
EXPECT_FALSE(got_load_start_);
|
||||
EXPECT_FALSE(got_cancel_load_);
|
||||
EXPECT_FALSE(got_load_error_);
|
||||
EXPECT_FALSE(got_load_end_);
|
||||
EXPECT_FALSE(got_loading_state_changed_end_);
|
||||
|
||||
const std::string& url = request->GetURL();
|
||||
EXPECT_STREQ(kCancelPageUrl, url.c_str());
|
||||
EXPECT_EQ(GetBrowserId(), browser->GetIdentifier());
|
||||
EXPECT_TRUE(frame->IsMain());
|
||||
|
||||
got_get_resource_handler_.yes();
|
||||
|
||||
CefPostDelayedTask(TID_UI,
|
||||
base::Bind(&CancelBeforeNavTestHandler::CancelLoad, this), 100);
|
||||
|
||||
return new UnstartedSchemeHandler();
|
||||
}
|
||||
|
||||
void OnLoadStart(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
TransitionType transition_type) override {
|
||||
EXPECT_TRUE(false); // Not reached.
|
||||
got_load_start_.yes();
|
||||
}
|
||||
|
||||
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int httpStatusCode) override {
|
||||
EXPECT_TRUE(false); // Not reached.
|
||||
got_load_end_.yes();
|
||||
}
|
||||
|
||||
void OnLoadError(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
ErrorCode errorCode,
|
||||
const CefString& errorText,
|
||||
const CefString& failedUrl) override {
|
||||
EXPECT_TRUE(got_loading_state_changed_start_);
|
||||
EXPECT_TRUE(got_before_browse_);
|
||||
EXPECT_TRUE(got_get_resource_handler_);
|
||||
EXPECT_FALSE(got_load_start_);
|
||||
EXPECT_TRUE(got_cancel_load_);
|
||||
EXPECT_FALSE(got_load_error_);
|
||||
EXPECT_FALSE(got_load_end_);
|
||||
EXPECT_FALSE(got_loading_state_changed_end_);
|
||||
|
||||
const std::string& url = failedUrl;
|
||||
EXPECT_STREQ(kCancelPageUrl, url.c_str());
|
||||
EXPECT_EQ(GetBrowserId(), browser->GetIdentifier());
|
||||
EXPECT_TRUE(frame->IsMain());
|
||||
|
||||
got_load_error_.yes();
|
||||
}
|
||||
|
||||
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
||||
bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) override {
|
||||
const std::string& url = browser->GetMainFrame()->GetURL();
|
||||
EXPECT_EQ(GetBrowserId(), browser->GetIdentifier());
|
||||
EXPECT_TRUE(url.empty());
|
||||
|
||||
if (isLoading) {
|
||||
EXPECT_FALSE(got_loading_state_changed_start_);
|
||||
EXPECT_FALSE(got_before_browse_);
|
||||
EXPECT_FALSE(got_get_resource_handler_);
|
||||
EXPECT_FALSE(got_load_start_);
|
||||
EXPECT_FALSE(got_cancel_load_);
|
||||
EXPECT_FALSE(got_load_error_);
|
||||
EXPECT_FALSE(got_load_end_);
|
||||
EXPECT_FALSE(got_loading_state_changed_end_);
|
||||
|
||||
got_loading_state_changed_start_.yes();
|
||||
} else {
|
||||
EXPECT_TRUE(got_loading_state_changed_start_);
|
||||
EXPECT_TRUE(got_before_browse_);
|
||||
EXPECT_TRUE(got_get_resource_handler_);
|
||||
EXPECT_FALSE(got_load_start_);
|
||||
EXPECT_TRUE(got_cancel_load_);
|
||||
EXPECT_TRUE(got_load_error_);
|
||||
EXPECT_FALSE(got_load_end_);
|
||||
EXPECT_FALSE(got_loading_state_changed_end_);
|
||||
|
||||
got_loading_state_changed_end_.yes();
|
||||
|
||||
DestroyTest();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void CancelLoad() {
|
||||
got_cancel_load_.yes();
|
||||
GetBrowser()->StopLoad();
|
||||
}
|
||||
|
||||
void DestroyTest() override {
|
||||
if (destroyed_)
|
||||
return;
|
||||
destroyed_ = true;
|
||||
|
||||
EXPECT_TRUE(got_loading_state_changed_start_);
|
||||
EXPECT_TRUE(got_before_browse_);
|
||||
EXPECT_TRUE(got_get_resource_handler_);
|
||||
EXPECT_FALSE(got_load_start_);
|
||||
EXPECT_TRUE(got_cancel_load_);
|
||||
EXPECT_TRUE(got_load_error_);
|
||||
EXPECT_FALSE(got_load_end_);
|
||||
EXPECT_TRUE(got_loading_state_changed_end_);
|
||||
|
||||
TestHandler::DestroyTest();
|
||||
}
|
||||
|
||||
bool destroyed_;
|
||||
|
||||
TrackCallback got_loading_state_changed_start_;
|
||||
TrackCallback got_before_browse_;
|
||||
TrackCallback got_get_resource_handler_;
|
||||
TrackCallback got_load_start_;
|
||||
TrackCallback got_cancel_load_;
|
||||
TrackCallback got_load_error_;
|
||||
TrackCallback got_load_end_;
|
||||
TrackCallback got_loading_state_changed_end_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(CancelBeforeNavTestHandler);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// Test that navigation canceled before commit does not call
|
||||
// OnLoadStart/OnLoadEnd.
|
||||
TEST(NavigationTest, CancelBeforeCommit) {
|
||||
CefRefPtr<CancelBeforeNavTestHandler> handler =
|
||||
new CancelBeforeNavTestHandler();
|
||||
handler->ExecuteTest();
|
||||
ReleaseAndWaitForDestructor(handler);
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
// A scheme handler that stalls after writing some data.
|
||||
class StalledSchemeHandler : public CefResourceHandler {
|
||||
public:
|
||||
StalledSchemeHandler() : offset_(0), write_size_(0) {}
|
||||
|
||||
bool ProcessRequest(CefRefPtr<CefRequest> request,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
callback->Continue();
|
||||
return true;
|
||||
}
|
||||
|
||||
void GetResponseHeaders(CefRefPtr<CefResponse> response,
|
||||
int64& response_length,
|
||||
CefString& redirectUrl) override {
|
||||
response->SetStatus(200);
|
||||
response->SetMimeType("text/html");
|
||||
content_ = "<html><body>Test</body></html>";
|
||||
// Write this number of bytes and then stall.
|
||||
write_size_ = content_.size() / 2U;
|
||||
response_length = content_.size();
|
||||
}
|
||||
|
||||
void Cancel() override {
|
||||
callback_ = nullptr;
|
||||
}
|
||||
|
||||
bool ReadResponse(void* data_out,
|
||||
int bytes_to_read,
|
||||
int& bytes_read,
|
||||
CefRefPtr<CefCallback> callback) override {
|
||||
size_t size = content_.size();
|
||||
if (offset_ >= write_size_) {
|
||||
// Now stall.
|
||||
bytes_read = 0;
|
||||
callback_ = callback;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (offset_ < size) {
|
||||
// Write up to |write_size_| bytes.
|
||||
int transfer_size =
|
||||
std::min(bytes_to_read, std::min(static_cast<int>(write_size_),
|
||||
static_cast<int>(size - offset_)));
|
||||
memcpy(data_out, content_.c_str() + offset_, transfer_size);
|
||||
offset_ += transfer_size;
|
||||
|
||||
bytes_read = transfer_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string content_;
|
||||
size_t offset_;
|
||||
size_t write_size_;
|
||||
CefRefPtr<CefCallback> callback_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(StalledSchemeHandler);
|
||||
};
|
||||
|
||||
// Browser side.
|
||||
class CancelAfterNavTestHandler : public TestHandler {
|
||||
public:
|
||||
CancelAfterNavTestHandler()
|
||||
: destroyed_(false) {}
|
||||
|
||||
void RunTest() override {
|
||||
// Create the browser.
|
||||
CreateBrowser(kCancelPageUrl);
|
||||
|
||||
// Time out the test after a reasonable period of time.
|
||||
SetTestTimeout();
|
||||
}
|
||||
|
||||
bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request,
|
||||
bool is_redirect) override {
|
||||
EXPECT_TRUE(got_loading_state_changed_start_);
|
||||
EXPECT_FALSE(got_before_browse_);
|
||||
EXPECT_FALSE(got_get_resource_handler_);
|
||||
EXPECT_FALSE(got_load_start_);
|
||||
EXPECT_FALSE(got_cancel_load_);
|
||||
EXPECT_FALSE(got_load_error_);
|
||||
EXPECT_FALSE(got_load_end_);
|
||||
EXPECT_FALSE(got_loading_state_changed_end_);
|
||||
|
||||
const std::string& url = request->GetURL();
|
||||
EXPECT_STREQ(kCancelPageUrl, url.c_str());
|
||||
EXPECT_EQ(GetBrowserId(), browser->GetIdentifier());
|
||||
EXPECT_TRUE(frame->IsMain());
|
||||
|
||||
got_before_browse_.yes();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CefRefPtr<CefResourceHandler> GetResourceHandler(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
CefRefPtr<CefRequest> request) override {
|
||||
EXPECT_TRUE(got_loading_state_changed_start_);
|
||||
EXPECT_TRUE(got_before_browse_);
|
||||
EXPECT_FALSE(got_get_resource_handler_);
|
||||
EXPECT_FALSE(got_load_start_);
|
||||
EXPECT_FALSE(got_cancel_load_);
|
||||
EXPECT_FALSE(got_load_error_);
|
||||
EXPECT_FALSE(got_load_end_);
|
||||
EXPECT_FALSE(got_loading_state_changed_end_);
|
||||
|
||||
const std::string& url = request->GetURL();
|
||||
EXPECT_STREQ(kCancelPageUrl, url.c_str());
|
||||
EXPECT_EQ(GetBrowserId(), browser->GetIdentifier());
|
||||
EXPECT_TRUE(frame->IsMain());
|
||||
|
||||
got_get_resource_handler_.yes();
|
||||
|
||||
CefPostDelayedTask(TID_UI,
|
||||
base::Bind(&CancelAfterNavTestHandler::CancelLoad, this), 100);
|
||||
|
||||
return new StalledSchemeHandler();
|
||||
}
|
||||
|
||||
void OnLoadStart(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
TransitionType transition_type) override {
|
||||
EXPECT_TRUE(got_loading_state_changed_start_);
|
||||
EXPECT_TRUE(got_before_browse_);
|
||||
EXPECT_TRUE(got_get_resource_handler_);
|
||||
EXPECT_FALSE(got_load_start_);
|
||||
EXPECT_FALSE(got_cancel_load_);
|
||||
EXPECT_FALSE(got_load_error_);
|
||||
EXPECT_FALSE(got_load_end_);
|
||||
EXPECT_FALSE(got_loading_state_changed_end_);
|
||||
|
||||
const std::string& url = frame->GetURL();
|
||||
EXPECT_STREQ(kCancelPageUrl, url.c_str());
|
||||
EXPECT_EQ(GetBrowserId(), browser->GetIdentifier());
|
||||
EXPECT_TRUE(frame->IsMain());
|
||||
|
||||
got_load_start_.yes();
|
||||
}
|
||||
|
||||
void OnLoadEnd(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
int httpStatusCode) override {
|
||||
EXPECT_TRUE(got_loading_state_changed_start_);
|
||||
EXPECT_TRUE(got_before_browse_);
|
||||
EXPECT_TRUE(got_get_resource_handler_);
|
||||
EXPECT_TRUE(got_load_start_);
|
||||
EXPECT_TRUE(got_cancel_load_);
|
||||
EXPECT_TRUE(got_load_error_);
|
||||
EXPECT_FALSE(got_load_end_);
|
||||
EXPECT_FALSE(got_loading_state_changed_end_);
|
||||
|
||||
const std::string& url = frame->GetURL();
|
||||
EXPECT_STREQ(kCancelPageUrl, url.c_str());
|
||||
EXPECT_EQ(GetBrowserId(), browser->GetIdentifier());
|
||||
EXPECT_TRUE(frame->IsMain());
|
||||
|
||||
got_load_end_.yes();
|
||||
DestroyTestIfDone();
|
||||
}
|
||||
|
||||
void OnLoadError(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
ErrorCode errorCode,
|
||||
const CefString& errorText,
|
||||
const CefString& failedUrl) override {
|
||||
EXPECT_TRUE(got_loading_state_changed_start_);
|
||||
EXPECT_TRUE(got_before_browse_);
|
||||
EXPECT_TRUE(got_get_resource_handler_);
|
||||
EXPECT_TRUE(got_load_start_);
|
||||
EXPECT_TRUE(got_cancel_load_);
|
||||
EXPECT_FALSE(got_load_error_);
|
||||
EXPECT_FALSE(got_load_end_);
|
||||
EXPECT_FALSE(got_loading_state_changed_end_);
|
||||
|
||||
const std::string& url = failedUrl;
|
||||
EXPECT_STREQ(kCancelPageUrl, url.c_str());
|
||||
EXPECT_EQ(GetBrowserId(), browser->GetIdentifier());
|
||||
EXPECT_TRUE(frame->IsMain());
|
||||
|
||||
got_load_error_.yes();
|
||||
}
|
||||
|
||||
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
||||
bool isLoading,
|
||||
bool canGoBack,
|
||||
bool canGoForward) override {
|
||||
const std::string& url = browser->GetMainFrame()->GetURL();
|
||||
EXPECT_EQ(GetBrowserId(), browser->GetIdentifier());
|
||||
|
||||
if (isLoading) {
|
||||
EXPECT_FALSE(got_loading_state_changed_start_);
|
||||
EXPECT_FALSE(got_before_browse_);
|
||||
EXPECT_FALSE(got_get_resource_handler_);
|
||||
EXPECT_FALSE(got_load_start_);
|
||||
EXPECT_FALSE(got_cancel_load_);
|
||||
EXPECT_FALSE(got_load_error_);
|
||||
EXPECT_FALSE(got_load_end_);
|
||||
EXPECT_FALSE(got_loading_state_changed_end_);
|
||||
|
||||
EXPECT_TRUE(url.empty());
|
||||
|
||||
got_loading_state_changed_start_.yes();
|
||||
} else {
|
||||
EXPECT_TRUE(got_loading_state_changed_start_);
|
||||
EXPECT_TRUE(got_before_browse_);
|
||||
EXPECT_TRUE(got_get_resource_handler_);
|
||||
EXPECT_TRUE(got_load_start_);
|
||||
EXPECT_TRUE(got_cancel_load_);
|
||||
EXPECT_TRUE(got_load_error_);
|
||||
EXPECT_TRUE(got_load_end_);
|
||||
EXPECT_FALSE(got_loading_state_changed_end_);
|
||||
|
||||
EXPECT_STREQ(kCancelPageUrl, url.c_str());
|
||||
|
||||
got_loading_state_changed_end_.yes();
|
||||
DestroyTestIfDone();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void CancelLoad() {
|
||||
got_cancel_load_.yes();
|
||||
GetBrowser()->StopLoad();
|
||||
}
|
||||
|
||||
void DestroyTestIfDone() {
|
||||
if (got_loading_state_changed_end_ && got_load_end_)
|
||||
DestroyTest();
|
||||
}
|
||||
|
||||
void DestroyTest() override {
|
||||
if (destroyed_)
|
||||
return;
|
||||
destroyed_ = true;
|
||||
|
||||
EXPECT_TRUE(got_loading_state_changed_start_);
|
||||
EXPECT_TRUE(got_before_browse_);
|
||||
EXPECT_TRUE(got_get_resource_handler_);
|
||||
EXPECT_TRUE(got_load_start_);
|
||||
EXPECT_TRUE(got_cancel_load_);
|
||||
EXPECT_TRUE(got_load_error_);
|
||||
EXPECT_TRUE(got_load_end_);
|
||||
EXPECT_TRUE(got_loading_state_changed_end_);
|
||||
|
||||
TestHandler::DestroyTest();
|
||||
}
|
||||
|
||||
bool destroyed_;
|
||||
|
||||
TrackCallback got_loading_state_changed_start_;
|
||||
TrackCallback got_before_browse_;
|
||||
TrackCallback got_get_resource_handler_;
|
||||
TrackCallback got_load_start_;
|
||||
TrackCallback got_cancel_load_;
|
||||
TrackCallback got_load_error_;
|
||||
TrackCallback got_load_end_;
|
||||
TrackCallback got_loading_state_changed_end_;
|
||||
|
||||
IMPLEMENT_REFCOUNTING(CancelAfterNavTestHandler);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// Test that navigation canceled after commit calls everything.
|
||||
TEST(NavigationTest, CancelAfterCommit) {
|
||||
CefRefPtr<CancelAfterNavTestHandler> handler =
|
||||
new CancelAfterNavTestHandler();
|
||||
handler->ExecuteTest();
|
||||
ReleaseAndWaitForDestructor(handler);
|
||||
}
|
||||
|
||||
|
||||
// Entry point for creating navigation browser test objects.
|
||||
// Called from client_app_delegates.cc.
|
||||
|
Reference in New Issue
Block a user