mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-02 20:26:59 +01:00
Fix bugs and test failures with browser-side navigation (issue #2290)
This commit is contained in:
parent
493bec52c9
commit
69178d519e
2
BUILD.gn
2
BUILD.gn
@ -450,6 +450,8 @@ static_library("libcef_static") {
|
||||
"libcef/browser/net/devtools_scheme_handler.h",
|
||||
"libcef/browser/net/internal_scheme_handler.cc",
|
||||
"libcef/browser/net/internal_scheme_handler.h",
|
||||
"libcef/browser/net/net_util.cc",
|
||||
"libcef/browser/net/net_util.h",
|
||||
"libcef/browser/net/network_delegate.cc",
|
||||
"libcef/browser/net/network_delegate.h",
|
||||
"libcef/browser/net/resource_request_job.cc",
|
||||
|
@ -82,6 +82,10 @@ using content::KeyboardEventProcessingResult;
|
||||
|
||||
namespace {
|
||||
|
||||
const int kUnspecifiedFrameTreeNodeId = -3;
|
||||
const int kMainFrameTreeNodeId = -2;
|
||||
const int kUnusedFrameTreeNodeId = -1;
|
||||
|
||||
// Associates a CefBrowserHostImpl instance with a WebContents. This object will
|
||||
// be deleted automatically when the WebContents is destroyed.
|
||||
class WebContentsUserDataAdapter : public base::SupportsUserData::Data {
|
||||
@ -1390,7 +1394,9 @@ CefRefPtr<CefFrame> CefBrowserHostImpl::GetFrame(int64 identifier) {
|
||||
if (main_frame_id_ == CefFrameHostImpl::kInvalidFrameId) {
|
||||
// A main frame does not exist yet. Return the placeholder frame that
|
||||
// provides limited functionality.
|
||||
return placeholder_frame_.get();
|
||||
return GetOrCreatePendingFrame(kMainFrameTreeNodeId,
|
||||
CefFrameHostImpl::kInvalidFrameId, nullptr)
|
||||
.get();
|
||||
}
|
||||
|
||||
if (identifier == CefFrameHostImpl::kMainFrameId) {
|
||||
@ -1406,7 +1412,7 @@ CefRefPtr<CefFrame> CefBrowserHostImpl::GetFrame(int64 identifier) {
|
||||
if (identifier == CefFrameHostImpl::kInvalidFrameId)
|
||||
return nullptr;
|
||||
|
||||
FrameMap::const_iterator it = frames_.find(identifier);
|
||||
FrameIdMap::const_iterator it = frames_.find(identifier);
|
||||
if (it != frames_.end())
|
||||
return it->second.get();
|
||||
|
||||
@ -1416,7 +1422,7 @@ CefRefPtr<CefFrame> CefBrowserHostImpl::GetFrame(int64 identifier) {
|
||||
CefRefPtr<CefFrame> CefBrowserHostImpl::GetFrame(const CefString& name) {
|
||||
base::AutoLock lock_scope(state_lock_);
|
||||
|
||||
FrameMap::const_iterator it = frames_.begin();
|
||||
FrameIdMap::const_iterator it = frames_.begin();
|
||||
for (; it != frames_.end(); ++it) {
|
||||
if (it->second->GetName() == name)
|
||||
return it->second.get();
|
||||
@ -1436,7 +1442,7 @@ void CefBrowserHostImpl::GetFrameIdentifiers(std::vector<int64>& identifiers) {
|
||||
if (identifiers.size() > 0)
|
||||
identifiers.clear();
|
||||
|
||||
FrameMap::const_iterator it = frames_.begin();
|
||||
FrameIdMap::const_iterator it = frames_.begin();
|
||||
for (; it != frames_.end(); ++it)
|
||||
identifiers.push_back(it->first);
|
||||
}
|
||||
@ -1447,7 +1453,7 @@ void CefBrowserHostImpl::GetFrameNames(std::vector<CefString>& names) {
|
||||
if (names.size() > 0)
|
||||
names.clear();
|
||||
|
||||
FrameMap::const_iterator it = frames_.begin();
|
||||
FrameIdMap::const_iterator it = frames_.begin();
|
||||
for (; it != frames_.end(); ++it)
|
||||
names.push_back(it->second->GetName());
|
||||
}
|
||||
@ -1578,7 +1584,7 @@ CefRefPtr<CefFrame> CefBrowserHostImpl::GetFrameForRequest(
|
||||
content::ResourceRequestInfo::ForRequest(request);
|
||||
if (!info)
|
||||
return nullptr;
|
||||
return GetOrCreateFrame(info->GetRenderFrameID(),
|
||||
return GetOrCreateFrame(info->GetRenderFrameID(), info->GetFrameTreeNodeId(),
|
||||
CefFrameHostImpl::kUnspecifiedFrameId,
|
||||
info->IsMainFrame(), base::string16(), GURL());
|
||||
}
|
||||
@ -2198,10 +2204,10 @@ void CefBrowserHostImpl::AddNewContents(content::WebContents* source,
|
||||
void CefBrowserHostImpl::LoadingStateChanged(content::WebContents* source,
|
||||
bool to_different_document) {
|
||||
const int current_index =
|
||||
web_contents_->GetController().GetLastCommittedEntryIndex();
|
||||
const int max_index = web_contents_->GetController().GetEntryCount() - 1;
|
||||
source->GetController().GetLastCommittedEntryIndex();
|
||||
const int max_index = source->GetController().GetEntryCount() - 1;
|
||||
|
||||
const bool is_loading = web_contents_->IsLoading();
|
||||
const bool is_loading = source->IsLoading();
|
||||
const bool can_go_back = (current_index > 0);
|
||||
const bool can_go_forward = (current_index < max_index);
|
||||
|
||||
@ -2631,17 +2637,26 @@ void CefBrowserHostImpl::FrameDeleted(
|
||||
|
||||
base::AutoLock lock_scope(state_lock_);
|
||||
|
||||
const int64 frame_id = render_frame_host->GetRoutingID();
|
||||
FrameMap::iterator it = frames_.find(frame_id);
|
||||
if (it != frames_.end()) {
|
||||
it->second->Detach();
|
||||
frames_.erase(it);
|
||||
if (render_routing_id >= 0) {
|
||||
FrameIdMap::iterator it = frames_.find(render_routing_id);
|
||||
if (it != frames_.end()) {
|
||||
it->second->Detach();
|
||||
frames_.erase(it);
|
||||
}
|
||||
|
||||
if (main_frame_id_ == render_routing_id)
|
||||
main_frame_id_ = CefFrameHostImpl::kInvalidFrameId;
|
||||
if (focused_frame_id_ == render_routing_id)
|
||||
focused_frame_id_ = CefFrameHostImpl::kInvalidFrameId;
|
||||
}
|
||||
|
||||
if (main_frame_id_ == frame_id)
|
||||
main_frame_id_ = CefFrameHostImpl::kInvalidFrameId;
|
||||
if (focused_frame_id_ == frame_id)
|
||||
focused_frame_id_ = CefFrameHostImpl::kInvalidFrameId;
|
||||
if (frame_tree_node_id >= 0) {
|
||||
FrameTreeNodeIdMap::iterator it = pending_frames_.find(frame_tree_node_id);
|
||||
if (it != pending_frames_.end()) {
|
||||
it->second->Detach();
|
||||
pending_frames_.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::RenderViewCreated(
|
||||
@ -2654,6 +2669,9 @@ void CefBrowserHostImpl::RenderViewCreated(
|
||||
content::Source<content::RenderViewHost>(render_view_host));
|
||||
}
|
||||
|
||||
// RenderFrameCreated is otherwise not called for new popup browsers.
|
||||
RenderFrameCreated(render_view_host->GetMainFrame());
|
||||
|
||||
platform_delegate_->RenderViewCreated(render_view_host);
|
||||
}
|
||||
|
||||
@ -2706,25 +2724,28 @@ void CefBrowserHostImpl::RenderProcessGone(base::TerminationStatus status) {
|
||||
|
||||
void CefBrowserHostImpl::DidFinishNavigation(
|
||||
content::NavigationHandle* navigation_handle) {
|
||||
// This method may be called with a nullptr RenderFrameHost (RFH) when a
|
||||
// provisional load is started. It should be called again with a non-nullptr
|
||||
// RFH once the provisional load is committed or if the provisional load
|
||||
// fails.
|
||||
if (!navigation_handle->GetRenderFrameHost())
|
||||
return;
|
||||
|
||||
const net::Error error_code = navigation_handle->GetNetErrorCode();
|
||||
|
||||
// With PlzNavigate the RenderFrameHost will only be nullptr if the
|
||||
// provisional load fails, in which case |error_code| will be ERR_ABORTED.
|
||||
DCHECK(navigation_handle->GetRenderFrameHost() ||
|
||||
error_code == net::ERR_ABORTED);
|
||||
|
||||
const int64 frame_id =
|
||||
navigation_handle->GetRenderFrameHost()
|
||||
? navigation_handle->GetRenderFrameHost()->GetRoutingID()
|
||||
: CefFrameHostImpl::kUnspecifiedFrameId;
|
||||
const bool is_main_frame = navigation_handle->IsInMainFrame();
|
||||
const GURL& url =
|
||||
(error_code == net::OK ? navigation_handle->GetURL() : GURL());
|
||||
|
||||
CefRefPtr<CefFrame> frame =
|
||||
GetOrCreateFrame(frame_id, navigation_handle->GetFrameTreeNodeId(),
|
||||
CefFrameHostImpl::kUnspecifiedFrameId, is_main_frame,
|
||||
base::string16(), url);
|
||||
|
||||
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(
|
||||
navigation_handle->GetRenderFrameHost()->GetRoutingID(),
|
||||
CefFrameHostImpl::kUnspecifiedFrameId, is_main_frame, base::string16(),
|
||||
url);
|
||||
|
||||
// Don't call OnLoadStart for same page navigations (fragments,
|
||||
// history state).
|
||||
if (!navigation_handle->IsSameDocument())
|
||||
@ -2735,11 +2756,6 @@ void CefBrowserHostImpl::DidFinishNavigation(
|
||||
} 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);
|
||||
}
|
||||
@ -2768,9 +2784,11 @@ void CefBrowserHostImpl::DidFailLoad(
|
||||
// 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(), CefFrameHostImpl::kUnspecifiedFrameId,
|
||||
is_main_frame, base::string16(), validated_url);
|
||||
CefRefPtr<CefFrame> frame =
|
||||
GetOrCreateFrame(render_frame_host->GetRoutingID(),
|
||||
render_frame_host->GetFrameTreeNodeId(),
|
||||
CefFrameHostImpl::kUnspecifiedFrameId, is_main_frame,
|
||||
base::string16(), validated_url);
|
||||
OnLoadError(frame, validated_url, error_code);
|
||||
OnLoadEnd(frame, validated_url, error_code);
|
||||
}
|
||||
@ -2922,7 +2940,8 @@ void CefBrowserHostImpl::OnFrameIdentified(int64 frame_id,
|
||||
int64 parent_frame_id,
|
||||
base::string16 name) {
|
||||
bool is_main_frame = (parent_frame_id == CefFrameHostImpl::kMainFrameId);
|
||||
GetOrCreateFrame(frame_id, parent_frame_id, is_main_frame, name, GURL());
|
||||
GetOrCreateFrame(frame_id, kUnspecifiedFrameTreeNodeId, parent_frame_id,
|
||||
is_main_frame, name, GURL());
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::OnFrameFocused(
|
||||
@ -2937,13 +2956,13 @@ void CefBrowserHostImpl::OnFrameFocused(
|
||||
|
||||
if (focused_frame_id_ != CefFrameHostImpl::kInvalidFrameId) {
|
||||
// Unfocus the previously focused frame.
|
||||
FrameMap::const_iterator it = frames_.find(frame_id);
|
||||
FrameIdMap::const_iterator it = frames_.find(frame_id);
|
||||
if (it != frames_.end())
|
||||
unfocused_frame = it->second;
|
||||
}
|
||||
|
||||
// Focus the newly focused frame.
|
||||
FrameMap::iterator it = frames_.find(frame_id);
|
||||
FrameIdMap::iterator it = frames_.find(frame_id);
|
||||
if (it != frames_.end())
|
||||
focused_frame = it->second;
|
||||
|
||||
@ -2962,8 +2981,9 @@ void CefBrowserHostImpl::OnDidFinishLoad(int64 frame_id,
|
||||
bool is_main_frame,
|
||||
int http_status_code) {
|
||||
CefRefPtr<CefFrame> frame =
|
||||
GetOrCreateFrame(frame_id, CefFrameHostImpl::kUnspecifiedFrameId,
|
||||
is_main_frame, base::string16(), validated_url);
|
||||
GetOrCreateFrame(frame_id, kUnspecifiedFrameTreeNodeId,
|
||||
CefFrameHostImpl::kUnspecifiedFrameId, is_main_frame,
|
||||
base::string16(), validated_url);
|
||||
|
||||
// Give internal scheme handlers an opportunity to update content.
|
||||
scheme::DidFinishLoad(frame, validated_url);
|
||||
@ -3117,10 +3137,6 @@ CefBrowserHostImpl::CefBrowserHostImpl(
|
||||
|
||||
response_manager_.reset(new CefResponseManager);
|
||||
|
||||
placeholder_frame_ = new CefFrameHostImpl(
|
||||
this, CefFrameHostImpl::kInvalidFrameId, true, CefString(), CefString(),
|
||||
CefFrameHostImpl::kInvalidFrameId);
|
||||
|
||||
PrefsTabHelper::CreateForWebContents(web_contents_.get());
|
||||
printing::CefPrintViewManager::CreateForWebContents(web_contents_.get());
|
||||
|
||||
@ -3209,13 +3225,13 @@ void CefBrowserHostImpl::OnExtensionHostDeleted() {
|
||||
|
||||
CefRefPtr<CefFrame> CefBrowserHostImpl::GetOrCreateFrame(
|
||||
int64 frame_id,
|
||||
int frame_tree_node_id,
|
||||
int64 parent_frame_id,
|
||||
bool is_main_frame,
|
||||
base::string16 frame_name,
|
||||
const GURL& frame_url) {
|
||||
DCHECK(frame_id > CefFrameHostImpl::kInvalidFrameId);
|
||||
if (frame_id <= CefFrameHostImpl::kInvalidFrameId)
|
||||
return nullptr;
|
||||
// We need either a valid |frame_id| or a valid |frame_tree_node_id|.
|
||||
DCHECK(frame_id >= 0 || frame_tree_node_id >= kUnusedFrameTreeNodeId);
|
||||
|
||||
CefString url;
|
||||
if (frame_url.is_valid())
|
||||
@ -3228,13 +3244,50 @@ CefRefPtr<CefFrame> CefBrowserHostImpl::GetOrCreateFrame(
|
||||
CefRefPtr<CefFrameHostImpl> frame;
|
||||
bool frame_created = false;
|
||||
|
||||
{
|
||||
base::AutoLock lock_scope(state_lock_);
|
||||
base::AutoLock lock_scope(state_lock_);
|
||||
|
||||
if (frame_id < 0) {
|
||||
// With PlzNavigate the renderer process representation might not exist yet.
|
||||
if (is_main_frame && main_frame_id_ != CefFrameHostImpl::kInvalidFrameId) {
|
||||
// Operating in the main frame. Continue using the existing main frame
|
||||
// object until the new renderer process representation is created.
|
||||
frame_id = main_frame_id_;
|
||||
} else {
|
||||
if (is_main_frame) {
|
||||
// Always use the same pending object for the main frame.
|
||||
frame_tree_node_id = kMainFrameTreeNodeId;
|
||||
}
|
||||
|
||||
// Operating in a sub-frame, or the main frame hasn't yet navigated for
|
||||
// the first time. Use a pending object keyed on |frame_tree_node_id|.
|
||||
frame = GetOrCreatePendingFrame(frame_tree_node_id, parent_frame_id,
|
||||
&frame_created);
|
||||
}
|
||||
}
|
||||
|
||||
if (!frame) {
|
||||
// Delete the pending object, if any.
|
||||
{
|
||||
FrameTreeNodeIdMap::iterator it =
|
||||
pending_frames_.find(frame_tree_node_id);
|
||||
if (it != pending_frames_.end()) {
|
||||
DCHECK_EQ(is_main_frame, it->second->IsMain());
|
||||
|
||||
// Persist URL and name to the new frame.
|
||||
if (url.empty())
|
||||
url = it->second->GetURL();
|
||||
if (name.empty())
|
||||
name = it->second->GetName();
|
||||
|
||||
pending_frames_.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the main frame object if the ID has changed.
|
||||
if (is_main_frame && main_frame_id_ != frame_id) {
|
||||
if (main_frame_id_ != CefFrameHostImpl::kInvalidFrameId) {
|
||||
// Remove the old main frame object before adding the new one.
|
||||
FrameMap::iterator it = frames_.find(main_frame_id_);
|
||||
FrameIdMap::iterator it = frames_.find(main_frame_id_);
|
||||
if (it != frames_.end()) {
|
||||
// Persist URL and name to the new main frame.
|
||||
if (url.empty())
|
||||
@ -3249,15 +3302,18 @@ CefRefPtr<CefFrame> CefBrowserHostImpl::GetOrCreateFrame(
|
||||
if (focused_frame_id_ == main_frame_id_)
|
||||
focused_frame_id_ = frame_id;
|
||||
}
|
||||
|
||||
main_frame_id_ = frame_id;
|
||||
}
|
||||
|
||||
// Check if a frame object already exists.
|
||||
FrameMap::const_iterator it = frames_.find(frame_id);
|
||||
if (it != frames_.end())
|
||||
frame = it->second.get();
|
||||
// Check if a frame object already exists for the ID. If so, re-use it.
|
||||
{
|
||||
FrameIdMap::const_iterator it = frames_.find(frame_id);
|
||||
if (it != frames_.end())
|
||||
frame = it->second;
|
||||
}
|
||||
|
||||
if (!frame.get()) {
|
||||
if (!frame) {
|
||||
frame = new CefFrameHostImpl(this, frame_id, is_main_frame, url, name,
|
||||
parent_frame_id);
|
||||
frame_created = true;
|
||||
@ -3266,13 +3322,40 @@ CefRefPtr<CefFrame> CefBrowserHostImpl::GetOrCreateFrame(
|
||||
}
|
||||
|
||||
if (!frame_created)
|
||||
frame->SetAttributes(url, name, parent_frame_id);
|
||||
frame->SetAttributes(is_main_frame, url, name, parent_frame_id);
|
||||
|
||||
return frame.get();
|
||||
}
|
||||
|
||||
CefRefPtr<CefFrameHostImpl> CefBrowserHostImpl::GetOrCreatePendingFrame(
|
||||
int frame_tree_node_id,
|
||||
int64 parent_frame_id,
|
||||
bool* created) {
|
||||
const bool is_main_frame = (frame_tree_node_id == kMainFrameTreeNodeId);
|
||||
DCHECK(is_main_frame || frame_tree_node_id >= 0);
|
||||
|
||||
state_lock_.AssertAcquired();
|
||||
|
||||
FrameTreeNodeIdMap::const_iterator it =
|
||||
pending_frames_.find(frame_tree_node_id);
|
||||
if (it != pending_frames_.end()) {
|
||||
DCHECK_EQ(is_main_frame, it->second->IsMain());
|
||||
return it->second;
|
||||
}
|
||||
|
||||
CefRefPtr<CefFrameHostImpl> frame = new CefFrameHostImpl(
|
||||
this, CefFrameHostImpl::kInvalidFrameId, is_main_frame, CefString(),
|
||||
CefString(), parent_frame_id);
|
||||
pending_frames_.insert(std::make_pair(frame_tree_node_id, frame));
|
||||
if (created)
|
||||
*created = true;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
void CefBrowserHostImpl::DetachAllFrames() {
|
||||
FrameMap frames;
|
||||
FrameIdMap frames;
|
||||
FrameTreeNodeIdMap pending_frames;
|
||||
|
||||
{
|
||||
base::AutoLock lock_scope(state_lock_);
|
||||
@ -3280,15 +3363,26 @@ void CefBrowserHostImpl::DetachAllFrames() {
|
||||
frames = frames_;
|
||||
frames_.clear();
|
||||
|
||||
pending_frames = pending_frames_;
|
||||
pending_frames_.clear();
|
||||
|
||||
if (main_frame_id_ != CefFrameHostImpl::kInvalidFrameId)
|
||||
main_frame_id_ = CefFrameHostImpl::kInvalidFrameId;
|
||||
if (focused_frame_id_ != CefFrameHostImpl::kInvalidFrameId)
|
||||
focused_frame_id_ = CefFrameHostImpl::kInvalidFrameId;
|
||||
}
|
||||
|
||||
FrameMap::const_iterator it = frames.begin();
|
||||
for (; it != frames.end(); ++it)
|
||||
it->second->Detach();
|
||||
{
|
||||
FrameIdMap::const_iterator it = frames.begin();
|
||||
for (; it != frames.end(); ++it)
|
||||
it->second->Detach();
|
||||
}
|
||||
|
||||
{
|
||||
FrameTreeNodeIdMap::const_iterator it = pending_frames.begin();
|
||||
for (; it != pending_frames.end(); ++it)
|
||||
it->second->Detach();
|
||||
}
|
||||
}
|
||||
|
||||
gfx::Point CefBrowserHostImpl::GetScreenPoint(const gfx::Point& view) const {
|
||||
|
@ -586,13 +586,36 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
void DestroyExtensionHost();
|
||||
void OnExtensionHostDeleted();
|
||||
|
||||
// Updates and returns an existing frame or creates a new frame. Pass
|
||||
// CefFrameHostImpl::kUnspecifiedFrameId for |parent_frame_id| if unknown.
|
||||
// Update or create a frame object. |frame_id| (renderer routing id) will be
|
||||
// >= 0 if the frame currently exists in the renderer process. |frame_id| will
|
||||
// be < 0 for the main frame if it has not yet navigated for the first time,
|
||||
// or for sub-frames if PlzNavigate is enabled and the sub-frame does not yet
|
||||
// have a renderer process representation. |frame_tree_node_id| will be
|
||||
// kUnspecifiedFrameTreeNodeId for calls that originate from the renderer
|
||||
// process (meaning that |frame_id| should be >= 0); kUnusedFrameTreeNodeId
|
||||
// if PlzNavigate is disabled; or >= 0 otherwise. |parent_frame_id| will be
|
||||
// CefFrameHostImpl::kUnspecifiedFrameId if unknown. In cases where |frame_id|
|
||||
// is < 0 either the existing main frame object or a pending object will be
|
||||
// returned depending on current state.
|
||||
CefRefPtr<CefFrame> GetOrCreateFrame(int64 frame_id,
|
||||
int frame_tree_node_id,
|
||||
int64 parent_frame_id,
|
||||
bool is_main_frame,
|
||||
base::string16 frame_name,
|
||||
const GURL& frame_url);
|
||||
|
||||
// Returns a pending frame object. If the main frame has not yet navigated for
|
||||
// the first time then |frame_tree_node_id| will be kMainFrameTreeNodeId and a
|
||||
// single pending object will be returned. Otherwise, this method will be
|
||||
// called with a |frame_tree_node_id| value >= 0 when PlzNavigate is enabled
|
||||
// and there will then be one pending object for each frame that does not yet
|
||||
// have a renderer process representation. |parent_frame_id| will be
|
||||
// CefFrameHostImpl::kUnspecifiedFrameId if unknown. |created| will be set to
|
||||
// true if |created| is non-nullptr and the frame object was created.
|
||||
CefRefPtr<CefFrameHostImpl> GetOrCreatePendingFrame(int frame_tree_node_id,
|
||||
int64 parent_frame_id,
|
||||
bool* created);
|
||||
|
||||
// Remove the references to all frames and mark them as detached.
|
||||
void DetachAllFrames();
|
||||
|
||||
@ -636,15 +659,20 @@ class CefBrowserHostImpl : public CefBrowserHost,
|
||||
std::queue<IPC::Message*> queued_messages_;
|
||||
bool queue_messages_;
|
||||
|
||||
// Map of unique frame ids to CefFrameHostImpl references.
|
||||
typedef std::map<int64, CefRefPtr<CefFrameHostImpl>> FrameMap;
|
||||
FrameMap frames_;
|
||||
// Map of frame tree node id to CefFrameHostImpl. These are frames that do not
|
||||
// yet have a renderer process representation.
|
||||
typedef std::map<int, CefRefPtr<CefFrameHostImpl>> FrameTreeNodeIdMap;
|
||||
FrameTreeNodeIdMap pending_frames_;
|
||||
|
||||
// Map of unique frame id (renderer routing id) to CefFrameHostImpl. These are
|
||||
// frames that do have a renderer process representation.
|
||||
typedef std::map<int64, CefRefPtr<CefFrameHostImpl>> FrameIdMap;
|
||||
FrameIdMap frames_;
|
||||
|
||||
// The unique frame id currently identified as the main frame.
|
||||
int64 main_frame_id_;
|
||||
// The unique frame id currently identified as the focused frame.
|
||||
int64 focused_frame_id_;
|
||||
// Used when no other frame exists. Provides limited functionality.
|
||||
CefRefPtr<CefFrameHostImpl> placeholder_frame_;
|
||||
|
||||
// Represents the current browser destruction state. Only accessed on the UI
|
||||
// thread.
|
||||
|
@ -433,16 +433,6 @@ bool NavigationOnUIThread(
|
||||
return ignore_navigation;
|
||||
}
|
||||
|
||||
void FindFrameHostForNavigationHandle(
|
||||
content::NavigationHandle* navigation_handle,
|
||||
content::RenderFrameHost** matching_frame_host,
|
||||
content::RenderFrameHost* current_frame_host) {
|
||||
content::RenderFrameHostImpl* current_impl =
|
||||
static_cast<content::RenderFrameHostImpl*>(current_frame_host);
|
||||
if (current_impl->navigation_handle() == navigation_handle)
|
||||
*matching_frame_host = current_frame_host;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CefContentBrowserClient::CefContentBrowserClient() : browser_main_parts_(NULL) {
|
||||
@ -919,19 +909,12 @@ CefContentBrowserClient::CreateThrottlesForNavigation(
|
||||
|
||||
int64 parent_frame_id = CefFrameHostImpl::kUnspecifiedFrameId;
|
||||
if (!is_main_frame) {
|
||||
// Identify the RenderFrameHostImpl that originated the navigation.
|
||||
// TODO(cef): It would be better if NavigationHandle could directly report
|
||||
// the owner RenderFrameHostImpl.
|
||||
// There is additional complexity here if PlzNavigate is enabled. See
|
||||
// comments in content/browser/frame_host/navigation_handle_impl.h.
|
||||
content::WebContents* web_contents = navigation_handle->GetWebContents();
|
||||
content::RenderFrameHost* parent_frame_host = NULL;
|
||||
web_contents->ForEachFrame(base::Bind(FindFrameHostForNavigationHandle,
|
||||
navigation_handle,
|
||||
&parent_frame_host));
|
||||
// Identify the RenderFrameHost that originated the navigation.
|
||||
content::RenderFrameHost* parent_frame_host =
|
||||
navigation_handle->GetParentFrame();
|
||||
DCHECK(parent_frame_host);
|
||||
|
||||
parent_frame_id = parent_frame_host->GetRoutingID();
|
||||
if (parent_frame_host)
|
||||
parent_frame_id = parent_frame_host->GetRoutingID();
|
||||
if (parent_frame_id < 0)
|
||||
parent_frame_id = CefFrameHostImpl::kUnspecifiedFrameId;
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ void CefExtensionSystem::Init() {
|
||||
// CefExtensionWebContentsObserver::RenderViewCreated in the browser
|
||||
// process.
|
||||
if (PdfExtensionEnabled()) {
|
||||
LoadExtension(pdf_extension_util::GetManifest(),
|
||||
LoadExtension(ParseManifest(pdf_extension_util::GetManifest()),
|
||||
base::FilePath(FILE_PATH_LITERAL("pdf")), true /* internal */,
|
||||
nullptr, nullptr);
|
||||
}
|
||||
|
@ -212,10 +212,12 @@ void CefFrameHostImpl::SetFocused(bool focused) {
|
||||
is_focused_ = focused;
|
||||
}
|
||||
|
||||
void CefFrameHostImpl::SetAttributes(const CefString& url,
|
||||
void CefFrameHostImpl::SetAttributes(bool is_main_frame,
|
||||
const CefString& url,
|
||||
const CefString& name,
|
||||
int64 parent_frame_id) {
|
||||
base::AutoLock lock_scope(state_lock_);
|
||||
is_main_frame_ = is_main_frame;
|
||||
if (!url.empty() && url != url_)
|
||||
url_ = url;
|
||||
if (!name.empty() && name != name_)
|
||||
|
@ -57,7 +57,8 @@ class CefFrameHostImpl : public CefFrame {
|
||||
void VisitDOM(CefRefPtr<CefDOMVisitor> visitor) override;
|
||||
|
||||
void SetFocused(bool focused);
|
||||
void SetAttributes(const CefString& url,
|
||||
void SetAttributes(bool is_main_frame,
|
||||
const CefString& url,
|
||||
const CefString& name,
|
||||
int64 parent_frame_id);
|
||||
|
||||
|
22
libcef/browser/net/net_util.cc
Normal file
22
libcef/browser/net/net_util.cc
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#include "libcef/browser/net/net_util.h"
|
||||
|
||||
#include "net/url_request/url_request.h"
|
||||
#include "url/url_constants.h"
|
||||
|
||||
namespace net_util {
|
||||
|
||||
bool IsInternalRequest(net::URLRequest* request) {
|
||||
// With PlzNavigate we now receive blob URLs. Ignore these URLs.
|
||||
// See https://crbug.com/776884 for details.
|
||||
if (request->url().SchemeIs(url::kBlobScheme)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}; // namespace net_util
|
21
libcef/browser/net/net_util.h
Normal file
21
libcef/browser/net/net_util.h
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright (c) 2017 The Chromium Embedded Framework Authors. All rights
|
||||
// reserved. Use of this source code is governed by a BSD-style license that
|
||||
// can be found in the LICENSE file.
|
||||
|
||||
#ifndef CEF_LIBCEF_BROWSER_NET_NET_UTIL_H_
|
||||
#define CEF_LIBCEF_BROWSER_NET_NET_UTIL_H_
|
||||
#pragma once
|
||||
|
||||
namespace net {
|
||||
class URLRequest;
|
||||
}
|
||||
|
||||
namespace net_util {
|
||||
|
||||
// Returns true if |request| is handled internally and should not be exposed via
|
||||
// the CEF API.
|
||||
bool IsInternalRequest(net::URLRequest* request);
|
||||
|
||||
}; // namespace net_util
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_NET_NET_UTIL_H_
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "include/cef_urlrequest.h"
|
||||
#include "libcef/browser/browser_host_impl.h"
|
||||
#include "libcef/browser/net/net_util.h"
|
||||
#include "libcef/browser/net/source_stream.h"
|
||||
#include "libcef/browser/net/url_request_user_data.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
@ -219,14 +220,9 @@ class CefAuthCallbackImpl : public CefAuthCallback {
|
||||
IMPLEMENT_REFCOUNTING(CefAuthCallbackImpl);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
CefNetworkDelegate::CefNetworkDelegate() : force_google_safesearch_(nullptr) {}
|
||||
|
||||
CefNetworkDelegate::~CefNetworkDelegate() {}
|
||||
|
||||
// static
|
||||
bool CefNetworkDelegate::AreExperimentalCookieFeaturesEnabled() {
|
||||
// Match the logic from ChromeNetworkDelegate and
|
||||
// RenderFrameMessageFilter::OnSetCookie.
|
||||
bool AreExperimentalCookieFeaturesEnabled() {
|
||||
static bool initialized = false;
|
||||
static bool enabled = false;
|
||||
if (!initialized) {
|
||||
@ -237,9 +233,18 @@ bool CefNetworkDelegate::AreExperimentalCookieFeaturesEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CefNetworkDelegate::CefNetworkDelegate() : force_google_safesearch_(nullptr) {}
|
||||
|
||||
CefNetworkDelegate::~CefNetworkDelegate() {}
|
||||
|
||||
std::unique_ptr<net::SourceStream> CefNetworkDelegate::CreateSourceStream(
|
||||
net::URLRequest* request,
|
||||
std::unique_ptr<net::SourceStream> upstream) {
|
||||
if (net_util::IsInternalRequest(request))
|
||||
return upstream;
|
||||
|
||||
CefRefPtr<CefResponseFilter> cef_filter;
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browser =
|
||||
@ -275,6 +280,9 @@ int CefNetworkDelegate::OnBeforeURLRequest(
|
||||
net::URLRequest* request,
|
||||
const net::CompletionCallback& callback,
|
||||
GURL* new_url) {
|
||||
if (net_util::IsInternalRequest(request))
|
||||
return net::OK;
|
||||
|
||||
const bool force_google_safesearch =
|
||||
(force_google_safesearch_ && force_google_safesearch_->GetValue());
|
||||
|
||||
@ -330,6 +338,9 @@ int CefNetworkDelegate::OnBeforeURLRequest(
|
||||
}
|
||||
|
||||
void CefNetworkDelegate::OnCompleted(net::URLRequest* request, bool started) {
|
||||
if (net_util::IsInternalRequest(request))
|
||||
return;
|
||||
|
||||
if (!started)
|
||||
return;
|
||||
|
||||
@ -381,6 +392,9 @@ net::NetworkDelegate::AuthRequiredResponse CefNetworkDelegate::OnAuthRequired(
|
||||
const net::AuthChallengeInfo& auth_info,
|
||||
const AuthCallback& callback,
|
||||
net::AuthCredentials* credentials) {
|
||||
if (net_util::IsInternalRequest(request))
|
||||
return AUTH_REQUIRED_RESPONSE_NO_ACTION;
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browser =
|
||||
CefBrowserHostImpl::GetBrowserForRequest(request);
|
||||
if (browser.get()) {
|
||||
@ -434,5 +448,5 @@ bool CefNetworkDelegate::OnCanAccessFile(
|
||||
}
|
||||
|
||||
bool CefNetworkDelegate::OnAreExperimentalCookieFeaturesEnabled() const {
|
||||
return AreExperimentalCookieFeaturesEnabled();
|
||||
return ::AreExperimentalCookieFeaturesEnabled();
|
||||
}
|
||||
|
@ -20,10 +20,6 @@ class CefNetworkDelegate : public net::NetworkDelegateImpl {
|
||||
CefNetworkDelegate();
|
||||
~CefNetworkDelegate() override;
|
||||
|
||||
// Match the logic from ChromeNetworkDelegate and
|
||||
// RenderFrameMessageFilter::OnSetCookie.
|
||||
static bool AreExperimentalCookieFeaturesEnabled();
|
||||
|
||||
void set_force_google_safesearch(BooleanPrefMember* force_google_safesearch) {
|
||||
force_google_safesearch_ = force_google_safesearch;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "libcef/browser/browser_host_impl.h"
|
||||
#include "libcef/browser/net/net_util.h"
|
||||
#include "libcef/browser/net/resource_request_job.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/common/net/http_header_utils.h"
|
||||
@ -29,11 +30,8 @@ CefRequestInterceptor::~CefRequestInterceptor() {
|
||||
net::URLRequestJob* CefRequestInterceptor::MaybeInterceptRequest(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const {
|
||||
// With PlzNavigate we now receive blob URLs here.
|
||||
// Ignore these URLs. See https://crbug.com/776884 for details.
|
||||
if (request->url().SchemeIs(url::kBlobScheme)) {
|
||||
if (net_util::IsInternalRequest(request))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browser =
|
||||
CefBrowserHostImpl::GetBrowserForRequest(request);
|
||||
@ -59,13 +57,16 @@ net::URLRequestJob* CefRequestInterceptor::MaybeInterceptRequest(
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
net::URLRequestJob* CefRequestInterceptor::MaybeInterceptRedirect(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate,
|
||||
const GURL& location) const {
|
||||
if (net_util::IsInternalRequest(request))
|
||||
return nullptr;
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browser =
|
||||
CefBrowserHostImpl::GetBrowserForRequest(request);
|
||||
if (browser.get()) {
|
||||
@ -100,24 +101,27 @@ net::URLRequestJob* CefRequestInterceptor::MaybeInterceptRedirect(
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
net::URLRequestJob* CefRequestInterceptor::MaybeInterceptResponse(
|
||||
net::URLRequest* request,
|
||||
net::NetworkDelegate* network_delegate) const {
|
||||
if (net_util::IsInternalRequest(request))
|
||||
return nullptr;
|
||||
|
||||
CefRefPtr<CefBrowserHostImpl> browser =
|
||||
CefBrowserHostImpl::GetBrowserForRequest(request);
|
||||
if (!browser.get())
|
||||
return NULL;
|
||||
return nullptr;
|
||||
|
||||
CefRefPtr<CefClient> client = browser->GetClient();
|
||||
if (!client.get())
|
||||
return NULL;
|
||||
return nullptr;
|
||||
|
||||
CefRefPtr<CefRequestHandler> handler = client->GetRequestHandler();
|
||||
if (!handler.get())
|
||||
return NULL;
|
||||
return nullptr;
|
||||
|
||||
CefRefPtr<CefFrame> frame = browser->GetFrameForRequest(request);
|
||||
|
||||
@ -132,7 +136,7 @@ net::URLRequestJob* CefRequestInterceptor::MaybeInterceptResponse(
|
||||
// Give the client an opportunity to retry or redirect the request.
|
||||
if (!handler->OnResourceResponse(browser.get(), frame, cefRequest.get(),
|
||||
cefResponse.get())) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// This flag will be reset by URLRequest::RestartWithJob() calling
|
||||
|
@ -24,6 +24,10 @@ bool CefPluginServiceFilter::IsPluginAvailable(
|
||||
bool is_main_frame,
|
||||
const url::Origin& main_frame_origin,
|
||||
content::WebPluginInfo* plugin) {
|
||||
// With PlzNavigate this can be called before the renderer process exists.
|
||||
if (render_process_id < 0)
|
||||
return true;
|
||||
|
||||
CefResourceContext* resource_context = const_cast<CefResourceContext*>(
|
||||
reinterpret_cast<const CefResourceContext*>(context));
|
||||
CefViewHostMsg_GetPluginInfo_Status status =
|
||||
|
@ -9,7 +9,7 @@
|
||||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=9a3b6de92214d6b132bd66d84724272c886a3758$
|
||||
// $hash=778fe7c495b5646ffbed281f033ef1bd51f82a4f$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_WRAPPER_TYPES_H_
|
||||
|
@ -736,9 +736,14 @@ class FrameNavExpectationsRendererSingleNav
|
||||
V_EXPECT_TRUE(got_load_end_);
|
||||
V_EXPECT_TRUE(got_loading_state_change_start_);
|
||||
V_EXPECT_TRUE(got_loading_state_change_end_);
|
||||
V_EXPECT_TRUE(got_before_navigation_);
|
||||
V_EXPECT_FALSE(got_finalize_);
|
||||
|
||||
if (IsBrowserSideNavigationEnabled()) {
|
||||
V_EXPECT_FALSE(got_before_navigation_);
|
||||
} else {
|
||||
V_EXPECT_TRUE(got_before_navigation_);
|
||||
}
|
||||
|
||||
got_finalize_.yes();
|
||||
|
||||
V_RETURN();
|
||||
@ -1018,8 +1023,10 @@ class FrameNavExpectationsBrowserTestSingleNav
|
||||
CefRefPtr<CefFrame> frame,
|
||||
const std::string& url) override {
|
||||
V_DECLARE();
|
||||
V_EXPECT_TRUE(
|
||||
VerifySingleBrowserFrames(browser, frame, true, std::string()));
|
||||
// When browser-side navigation is enabled this method will be called
|
||||
// before the frame is created.
|
||||
V_EXPECT_TRUE(VerifySingleBrowserFrames(
|
||||
browser, frame, !IsBrowserSideNavigationEnabled(), std::string()));
|
||||
V_EXPECT_TRUE(parent::OnBeforeBrowse(browser, frame, url));
|
||||
V_RETURN();
|
||||
}
|
||||
@ -1027,8 +1034,10 @@ class FrameNavExpectationsBrowserTestSingleNav
|
||||
bool GetResourceHandler(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame) override {
|
||||
V_DECLARE();
|
||||
V_EXPECT_TRUE(
|
||||
VerifySingleBrowserFrames(browser, frame, true, std::string()));
|
||||
// When browser-side navigation is enabled this method will be called
|
||||
// before the frame is created.
|
||||
V_EXPECT_TRUE(VerifySingleBrowserFrames(
|
||||
browser, frame, !IsBrowserSideNavigationEnabled(), std::string()));
|
||||
V_EXPECT_TRUE(parent::GetResourceHandler(browser, frame));
|
||||
V_RETURN();
|
||||
}
|
||||
@ -1527,8 +1536,11 @@ class FrameNavExpectationsBrowserTestMultiNav
|
||||
std::string expected_url;
|
||||
if (nav() > 0)
|
||||
expected_url = GetPreviousMainURL();
|
||||
V_EXPECT_TRUE(
|
||||
VerifySingleBrowserFrames(browser, frame, true, expected_url));
|
||||
// When browser-side navigation is enabled this method will be called
|
||||
// before the frame is created for the first navigation.
|
||||
V_EXPECT_TRUE(VerifySingleBrowserFrames(
|
||||
browser, frame, nav() == 0 ? !IsBrowserSideNavigationEnabled() : true,
|
||||
expected_url));
|
||||
V_EXPECT_TRUE(parent::OnBeforeBrowse(browser, frame, url));
|
||||
V_RETURN();
|
||||
}
|
||||
@ -1539,8 +1551,11 @@ class FrameNavExpectationsBrowserTestMultiNav
|
||||
std::string expected_url;
|
||||
if (nav() > 0)
|
||||
expected_url = GetPreviousMainURL();
|
||||
V_EXPECT_TRUE(
|
||||
VerifySingleBrowserFrames(browser, frame, true, expected_url));
|
||||
// When browser-side navigation is enabled this method will be called
|
||||
// before the frame is created for the first navigation.
|
||||
V_EXPECT_TRUE(VerifySingleBrowserFrames(
|
||||
browser, frame, nav() == 0 ? !IsBrowserSideNavigationEnabled() : true,
|
||||
expected_url));
|
||||
V_EXPECT_TRUE(parent::GetResourceHandler(browser, frame));
|
||||
V_RETURN();
|
||||
}
|
||||
@ -1723,33 +1738,48 @@ bool VerifyBrowserIframe(CefRefPtr<CefBrowser> browser,
|
||||
V_EXPECT_TRUE(frame2.get());
|
||||
|
||||
// Verify that the name matches.
|
||||
V_EXPECT_TRUE(frame0->GetName().ToString() == kFrame0Name);
|
||||
V_EXPECT_TRUE(frame1->GetName().ToString() == kFrame1Name);
|
||||
V_EXPECT_TRUE(frame2->GetName().ToString() == kFrame2Name);
|
||||
V_EXPECT_TRUE(frame0->GetName().ToString() == kFrame0Name)
|
||||
<< "expected: " << kFrame0Name
|
||||
<< " actual: " << frame0->GetName().ToString();
|
||||
V_EXPECT_TRUE(frame1->GetName().ToString() == kFrame1Name)
|
||||
<< "expected: " << kFrame1Name
|
||||
<< " actual: " << frame1->GetName().ToString();
|
||||
V_EXPECT_TRUE(frame2->GetName().ToString() == kFrame2Name)
|
||||
<< "expected: " << kFrame2Name
|
||||
<< " actual: " << frame2->GetName().ToString();
|
||||
|
||||
// Verify that the URL matches.
|
||||
frame0url = GetMultiNavURL(origin, 0);
|
||||
V_EXPECT_TRUE(frame0->GetURL() == frame0url);
|
||||
V_EXPECT_TRUE(frame0->GetURL() == frame0url)
|
||||
<< "expected: " << frame0url
|
||||
<< " actual: " << frame0->GetURL().ToString();
|
||||
frame1url = GetMultiNavURL(origin, 1);
|
||||
V_EXPECT_TRUE(frame1->GetURL() == frame1url);
|
||||
V_EXPECT_TRUE(frame1->GetURL() == frame1url)
|
||||
<< "expected: " << frame1url
|
||||
<< " actual: " << frame1->GetURL().ToString();
|
||||
frame2url = GetMultiNavURL(origin, 2);
|
||||
V_EXPECT_TRUE(frame2->GetURL() == frame2url);
|
||||
V_EXPECT_TRUE(frame2->GetURL() == frame2url)
|
||||
<< "expected: " << frame2url
|
||||
<< " actual: " << frame2->GetURL().ToString();
|
||||
|
||||
// Verify that the frame id is valid.
|
||||
frame0id = frame0->GetIdentifier();
|
||||
V_EXPECT_TRUE(frame0id > 0);
|
||||
V_EXPECT_TRUE(frame0id > 0) << "actual: " << frame0id;
|
||||
frame1id = frame1->GetIdentifier();
|
||||
V_EXPECT_TRUE(frame1id > 0);
|
||||
V_EXPECT_TRUE(frame1id > 0) << "actual: " << frame1id;
|
||||
frame2id = frame2->GetIdentifier();
|
||||
V_EXPECT_TRUE(frame2id > 0);
|
||||
V_EXPECT_TRUE(frame2id > 0) << "actual: " << frame2id;
|
||||
|
||||
// Verify that the current frame has the correct id.
|
||||
if (frame_number == 0) {
|
||||
V_EXPECT_TRUE(frame->GetIdentifier() == frame0id);
|
||||
V_EXPECT_TRUE(frame->GetIdentifier() == frame0id)
|
||||
<< "expected: " << frame0id << " actual: " << frame->GetIdentifier();
|
||||
} else if (frame_number == 1) {
|
||||
V_EXPECT_TRUE(frame->GetIdentifier() == frame1id);
|
||||
V_EXPECT_TRUE(frame->GetIdentifier() == frame1id)
|
||||
<< "expected: " << frame1id << " actual: " << frame->GetIdentifier();
|
||||
} else if (frame_number == 2) {
|
||||
V_EXPECT_TRUE(frame->GetIdentifier() == frame2id);
|
||||
V_EXPECT_TRUE(frame->GetIdentifier() == frame2id)
|
||||
<< "expected: " << frame2id << " actual: " << frame->GetIdentifier();
|
||||
}
|
||||
|
||||
// Find frames by id.
|
||||
@ -1761,33 +1791,46 @@ bool VerifyBrowserIframe(CefRefPtr<CefBrowser> browser,
|
||||
V_EXPECT_TRUE(frame2b.get());
|
||||
|
||||
// Verify that the id matches.
|
||||
V_EXPECT_TRUE(frame0b->GetIdentifier() == frame0id);
|
||||
V_EXPECT_TRUE(frame1b->GetIdentifier() == frame1id);
|
||||
V_EXPECT_TRUE(frame2b->GetIdentifier() == frame2id);
|
||||
V_EXPECT_TRUE(frame0b->GetIdentifier() == frame0id)
|
||||
<< "expected: " << frame0id << " actual: " << frame0b->GetIdentifier();
|
||||
V_EXPECT_TRUE(frame1b->GetIdentifier() == frame1id)
|
||||
<< "expected: " << frame1id << " actual: " << frame1b->GetIdentifier();
|
||||
V_EXPECT_TRUE(frame2b->GetIdentifier() == frame2id)
|
||||
<< "expected: " << frame2id << " actual: " << frame2b->GetIdentifier();
|
||||
|
||||
size_t frame_count = browser->GetFrameCount();
|
||||
V_EXPECT_TRUE(frame_count == 3U) << "actual " << frame_count;
|
||||
V_EXPECT_TRUE(frame_count == 3U) << "actual: " << frame_count;
|
||||
|
||||
// Verify the GetFrameNames result.
|
||||
std::vector<CefString> names;
|
||||
browser->GetFrameNames(names);
|
||||
V_EXPECT_TRUE(names.size() == 3U);
|
||||
V_EXPECT_TRUE(names[0].ToString() == kFrame0Name);
|
||||
V_EXPECT_TRUE(names[1].ToString() == kFrame1Name);
|
||||
V_EXPECT_TRUE(names[2].ToString() == kFrame2Name);
|
||||
V_EXPECT_TRUE(names.size() == 3U) << "actual: " << names.size();
|
||||
V_EXPECT_TRUE(names[0].ToString() == kFrame0Name)
|
||||
<< "expected: " << kFrame0Name << " actual: " << names[0].ToString();
|
||||
V_EXPECT_TRUE(names[1].ToString() == kFrame1Name)
|
||||
<< "expected: " << kFrame1Name << " actual: " << names[1].ToString();
|
||||
V_EXPECT_TRUE(names[2].ToString() == kFrame2Name)
|
||||
<< "expected: " << kFrame2Name << " actual: " << names[2].ToString();
|
||||
|
||||
// Verify the GetFrameIdentifiers result.
|
||||
std::vector<int64> idents;
|
||||
browser->GetFrameIdentifiers(idents);
|
||||
V_EXPECT_TRUE(idents.size() == 3U);
|
||||
V_EXPECT_TRUE(idents[0] == frame0->GetIdentifier());
|
||||
V_EXPECT_TRUE(idents[1] == frame1->GetIdentifier());
|
||||
V_EXPECT_TRUE(idents[2] == frame2->GetIdentifier());
|
||||
V_EXPECT_TRUE(idents.size() == 3U) << "actual: " << idents.size();
|
||||
V_EXPECT_TRUE(idents[0] == frame0id)
|
||||
<< "expected: " << frame0id << " actual: " << idents[0];
|
||||
V_EXPECT_TRUE(idents[1] == frame1id)
|
||||
<< "expected: " << frame1id << " actual: " << idents[1];
|
||||
V_EXPECT_TRUE(idents[2] == frame2id)
|
||||
<< "expected: " << frame2id << " actual: " << idents[2];
|
||||
|
||||
// Verify parent hierarchy.
|
||||
V_EXPECT_FALSE(frame0->GetParent().get());
|
||||
V_EXPECT_TRUE(frame1->GetParent()->GetIdentifier() == frame0id);
|
||||
V_EXPECT_TRUE(frame2->GetParent()->GetIdentifier() == frame1id);
|
||||
V_EXPECT_TRUE(frame1->GetParent()->GetIdentifier() == frame0id)
|
||||
<< "expected: " << frame0id
|
||||
<< " actual: " << frame1->GetParent()->GetIdentifier();
|
||||
V_EXPECT_TRUE(frame2->GetParent()->GetIdentifier() == frame1id)
|
||||
<< "expected: " << frame1id
|
||||
<< " actual: " << frame2->GetParent()->GetIdentifier();
|
||||
|
||||
V_RETURN();
|
||||
}
|
||||
|
@ -940,8 +940,7 @@ class RedirectTestHandler : public TestHandler {
|
||||
got_nav3_redirect_.yes();
|
||||
|
||||
EXPECT_EQ(303, response->GetStatus());
|
||||
EXPECT_STREQ("See Other",
|
||||
response->GetStatusText().ToString().c_str());
|
||||
EXPECT_STREQ("See Other", response->GetStatusText().ToString().c_str());
|
||||
EXPECT_STREQ("text/html", response->GetMimeType().ToString().c_str());
|
||||
} else {
|
||||
got_invalid_redirect_.yes();
|
||||
@ -1169,21 +1168,20 @@ class OrderNavLoadState {
|
||||
got_load_end_.yes();
|
||||
}
|
||||
|
||||
bool IsStarted() {
|
||||
bool IsStarted() const {
|
||||
return got_loading_state_start_ || got_loading_state_end_ ||
|
||||
got_load_start_ || got_load_end_;
|
||||
}
|
||||
|
||||
bool IsDone() {
|
||||
bool IsDone() const {
|
||||
return got_loading_state_start_ && got_loading_state_end_ &&
|
||||
got_load_start_ && got_load_end_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool Verify(bool got_loading_state_start,
|
||||
bool got_loading_state_end,
|
||||
bool got_load_start,
|
||||
bool got_load_end) {
|
||||
bool got_load_end) const {
|
||||
EXPECT_EQ(got_loading_state_start, got_loading_state_start_)
|
||||
<< "Popup: " << is_popup_ << "; Browser Side: " << browser_side_;
|
||||
EXPECT_EQ(got_loading_state_end, got_loading_state_end_)
|
||||
@ -1198,6 +1196,7 @@ class OrderNavLoadState {
|
||||
got_load_start == got_load_start_ && got_load_end == got_load_end_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool is_popup_;
|
||||
bool browser_side_;
|
||||
|
||||
@ -1384,6 +1383,15 @@ class OrderNavRendererTest : public ClientAppRenderer::Delegate,
|
||||
SendTestResultsIfDone(browser);
|
||||
}
|
||||
|
||||
void OnLoadError(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
ErrorCode errorCode,
|
||||
const CefString& errorText,
|
||||
const CefString& failedUrl) override {
|
||||
ADD_FAILURE() << "renderer OnLoadError url: " << failedUrl.ToString()
|
||||
<< " error: " << errorCode;
|
||||
}
|
||||
|
||||
protected:
|
||||
void SendTestResultsIfDone(CefRefPtr<CefBrowser> browser) {
|
||||
bool done = false;
|
||||
@ -1580,6 +1588,15 @@ class OrderNavTestHandler : public TestHandler {
|
||||
ContinueIfReady(browser);
|
||||
}
|
||||
|
||||
void OnLoadError(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
ErrorCode errorCode,
|
||||
const CefString& errorText,
|
||||
const CefString& failedUrl) override {
|
||||
ADD_FAILURE() << "browser OnLoadError url: " << failedUrl.ToString()
|
||||
<< " error: " << errorCode;
|
||||
}
|
||||
|
||||
bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
|
||||
CefProcessId source_process,
|
||||
CefRefPtr<CefProcessMessage> message) override {
|
||||
@ -1627,6 +1644,9 @@ class OrderNavTestHandler : public TestHandler {
|
||||
EXPECT_TRUE(got_before_browse_main_);
|
||||
EXPECT_TRUE(got_before_browse_popup_);
|
||||
|
||||
EXPECT_TRUE(state_main_.Verify(true, true, true, true));
|
||||
EXPECT_TRUE(state_popup_.Verify(true, true, true, true));
|
||||
|
||||
TestHandler::DestroyTest();
|
||||
}
|
||||
|
||||
@ -2405,8 +2425,15 @@ class PopupJSWindowOpenTestHandler : public TestHandler {
|
||||
void OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
|
||||
TestHandler::OnAfterCreated(browser);
|
||||
|
||||
if (browser->IsPopup())
|
||||
if (browser->IsPopup()) {
|
||||
after_created_ct_++;
|
||||
if (!popup1_)
|
||||
popup1_ = browser;
|
||||
else if (!popup2_)
|
||||
popup2_ = browser;
|
||||
else
|
||||
ADD_FAILURE();
|
||||
}
|
||||
}
|
||||
|
||||
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
||||
@ -2418,10 +2445,23 @@ class PopupJSWindowOpenTestHandler : public TestHandler {
|
||||
|
||||
if (browser->IsPopup()) {
|
||||
const std::string& url = browser->GetMainFrame()->GetURL();
|
||||
if (load_end_ct_ == 0)
|
||||
if (url == kPopupJSOpenPopupUrl) {
|
||||
EXPECT_TRUE(browser->IsSame(popup2_));
|
||||
popup2_ = nullptr;
|
||||
|
||||
if (IsBrowserSideNavigationEnabled()) {
|
||||
// OnLoadingStateChange is not currently called for browser-side
|
||||
// navigations of empty popups. See https://crbug.com/789252.
|
||||
// Explicitly close the empty popup here as a workaround.
|
||||
CloseBrowser(popup1_, true);
|
||||
popup1_ = nullptr;
|
||||
}
|
||||
} else {
|
||||
// Empty popup.
|
||||
EXPECT_TRUE(url.empty());
|
||||
else
|
||||
EXPECT_STREQ(kPopupJSOpenPopupUrl, url.c_str());
|
||||
EXPECT_TRUE(browser->IsSame(popup1_));
|
||||
popup1_ = nullptr;
|
||||
}
|
||||
|
||||
load_end_ct_++;
|
||||
CloseBrowser(browser, true);
|
||||
@ -2436,6 +2476,15 @@ class PopupJSWindowOpenTestHandler : public TestHandler {
|
||||
}
|
||||
}
|
||||
|
||||
void OnLoadError(CefRefPtr<CefBrowser> browser,
|
||||
CefRefPtr<CefFrame> frame,
|
||||
ErrorCode errorCode,
|
||||
const CefString& errorText,
|
||||
const CefString& failedUrl) override {
|
||||
ADD_FAILURE() << "OnLoadError url: " << failedUrl.ToString()
|
||||
<< " error: " << errorCode;
|
||||
}
|
||||
|
||||
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override {
|
||||
TestHandler::OnBeforeClose(browser);
|
||||
|
||||
@ -2448,12 +2497,22 @@ class PopupJSWindowOpenTestHandler : public TestHandler {
|
||||
void DestroyTest() override {
|
||||
EXPECT_EQ(2U, before_popup_ct_);
|
||||
EXPECT_EQ(2U, after_created_ct_);
|
||||
EXPECT_EQ(2U, load_end_ct_);
|
||||
EXPECT_EQ(2U, before_close_ct_);
|
||||
|
||||
if (IsBrowserSideNavigationEnabled()) {
|
||||
// OnLoadingStateChange is not currently called for browser-side
|
||||
// navigations of empty popups. See https://crbug.com/789252.
|
||||
EXPECT_EQ(1U, load_end_ct_);
|
||||
} else {
|
||||
EXPECT_EQ(2U, load_end_ct_);
|
||||
}
|
||||
|
||||
TestHandler::DestroyTest();
|
||||
}
|
||||
|
||||
CefRefPtr<CefBrowser> popup1_;
|
||||
CefRefPtr<CefBrowser> popup2_;
|
||||
|
||||
size_t before_popup_ct_;
|
||||
size_t after_created_ct_;
|
||||
size_t load_end_ct_;
|
||||
@ -3131,8 +3190,10 @@ class CancelAfterNavTestHandler : public TestHandler {
|
||||
|
||||
got_get_resource_handler_.yes();
|
||||
|
||||
CefPostDelayedTask(
|
||||
TID_UI, base::Bind(&CancelAfterNavTestHandler::CancelLoad, this), 100);
|
||||
// The required delay is longer when browser-side navigation is enabled.
|
||||
CefPostDelayedTask(TID_UI,
|
||||
base::Bind(&CancelAfterNavTestHandler::CancelLoad, this),
|
||||
IsBrowserSideNavigationEnabled() ? 500 : 100);
|
||||
|
||||
return new StalledSchemeHandler();
|
||||
}
|
||||
|
@ -361,7 +361,6 @@ class PluginTestHandler : public RoutingTestHandler,
|
||||
return new CefStreamResourceHandler("application/pdf", stream);
|
||||
}
|
||||
|
||||
NOTREACHED();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -855,7 +855,13 @@ class PopupNavTestHandler : public TestHandler {
|
||||
EXPECT_FALSE(got_popup_load_end2_);
|
||||
} else if (mode_ == NAVIGATE_AFTER_CREATION) {
|
||||
EXPECT_FALSE(got_popup_load_start_);
|
||||
EXPECT_TRUE(got_popup_load_error_);
|
||||
if (IsBrowserSideNavigationEnabled()) {
|
||||
// With browser-side navigation we will never actually begin the
|
||||
// navigation to the 1st popup URL, so there will be no load error.
|
||||
EXPECT_FALSE(got_popup_load_error_);
|
||||
} else {
|
||||
EXPECT_TRUE(got_popup_load_error_);
|
||||
}
|
||||
EXPECT_FALSE(got_popup_load_end_);
|
||||
EXPECT_TRUE(got_popup_load_start2_);
|
||||
EXPECT_FALSE(got_popup_load_error2_);
|
||||
|
@ -591,8 +591,10 @@ class TypeTestHandler : public TestHandler {
|
||||
if (destroyed_)
|
||||
return;
|
||||
|
||||
if (completed_browser_side_ && completed_render_side_)
|
||||
if (completed_browser_side_ &&
|
||||
(completed_render_side_ || IsBrowserSideNavigationEnabled())) {
|
||||
DestroyTest();
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyTest() override {
|
||||
@ -602,7 +604,11 @@ class TypeTestHandler : public TestHandler {
|
||||
|
||||
// Verify test expectations.
|
||||
EXPECT_TRUE(completed_browser_side_);
|
||||
EXPECT_TRUE(completed_render_side_);
|
||||
if (IsBrowserSideNavigationEnabled()) {
|
||||
EXPECT_FALSE(completed_render_side_);
|
||||
} else {
|
||||
EXPECT_TRUE(completed_render_side_);
|
||||
}
|
||||
EXPECT_TRUE(browse_expectations_.IsDone(true));
|
||||
EXPECT_TRUE(load_expectations_.IsDone(true));
|
||||
EXPECT_TRUE(get_expectations_.IsDone(true));
|
||||
|
@ -158,17 +158,11 @@ class TestSchemeHandler : public TestHandler {
|
||||
const CefString& errorText,
|
||||
const CefString& failedUrl) override {
|
||||
test_results_->got_error.yes();
|
||||
#if defined(OS_LINUX)
|
||||
// CustomStandardXHR* tests are flaky on Linux, sometimes returning
|
||||
// ERR_ABORTED. Make the tests less flaky by also accepting that value.
|
||||
// Tests sometimes also fail with ERR_ABORTED.
|
||||
if (!(test_results_->expected_error_code == 0 &&
|
||||
errorCode == ERR_ABORTED)) {
|
||||
EXPECT_EQ(test_results_->expected_error_code, errorCode);
|
||||
}
|
||||
#else
|
||||
// Check that the error code matches the expectation.
|
||||
EXPECT_EQ(test_results_->expected_error_code, errorCode);
|
||||
#endif
|
||||
DestroyTest();
|
||||
}
|
||||
|
||||
|
@ -490,3 +490,19 @@ bool TestFailed() {
|
||||
return ::testing::UnitTest::GetInstance()->Failed();
|
||||
}
|
||||
}
|
||||
|
||||
bool IsBrowserSideNavigationEnabled() {
|
||||
static bool initialized = false;
|
||||
static bool value = false; // Default value.
|
||||
if (!initialized) {
|
||||
CefRefPtr<CefCommandLine> command_line =
|
||||
CefCommandLine::GetGlobalCommandLine();
|
||||
if (command_line->HasSwitch("enable-browser-side-navigation")) {
|
||||
value = true;
|
||||
} else if (command_line->HasSwitch("disable-browser-side-navigation")) {
|
||||
value = false;
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
@ -327,6 +327,9 @@ void ReleaseAndWaitForDestructor(CefRefPtr<T>& handler, int delay_ms = 2000) {
|
||||
// Returns true if the currently running test has failed.
|
||||
bool TestFailed();
|
||||
|
||||
// Returns true if browser-side navigation is enabled.
|
||||
bool IsBrowserSideNavigationEnabled();
|
||||
|
||||
// Helper macros for executing checks in a method with a boolean return value.
|
||||
// For example:
|
||||
//
|
||||
|
Loading…
x
Reference in New Issue
Block a user