Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(835)

Unified Diff: content/browser/frame_host/navigator_impl.cc

Issue 135723003: Move DidCommitProvisionalLoad code from RenderView to RenderFrame. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed unit tests and removed WebContents::DidNavigate Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/frame_host/navigator_impl.cc
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
index 01032851d17f826c4eabfcbe208933a4aaa9ba05..c49f223d06ab64d4dfda83ad3d418327abdf3e7c 100644
--- a/content/browser/frame_host/navigator_impl.cc
+++ b/content/browser/frame_host/navigator_impl.cc
@@ -20,8 +20,10 @@
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/navigation_details.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/common/bindings_policy.h"
+#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
@@ -30,6 +32,11 @@ namespace content {
namespace {
+content::RenderFrameHostManager* GetRenderManager(
+ content::RenderFrameHostImpl* rfh) {
+ return rfh->frame_tree_node()->render_manager();
+}
+
ViewMsg_Navigate_Type::Value GetNavigationType(
BrowserContext* browser_context, const NavigationEntryImpl& entry,
NavigationController::ReloadType reload_type) {
@@ -361,4 +368,164 @@ base::TimeTicks NavigatorImpl::GetCurrentLoadStart() {
return current_load_start_;
}
+void NavigatorImpl::DidNavigate(
+ RenderFrameHostImpl* render_frame_host,
+ const FrameHostMsg_DidCommitProvisionalLoad_Params& input_params) {
Charlie Reis 2014/02/06 21:49:07 nit: Wrong indent (2 spaces too many)
nasko 2014/02/06 21:58:43 Done.
+ FrameHostMsg_DidCommitProvisionalLoad_Params params(input_params);
+ FrameTree* frame_tree = render_frame_host->frame_tree_node()->frame_tree();
+ RenderViewHostImpl* rvh = render_frame_host->render_view_host();
+ bool use_site_per_process =
+ CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess);
+ if (frame_tree->IsFirstNavigationAfterSwap()) {
+ // First navigation should be a main frame navigation.
+ // TODO(creis): This DCHECK is currently disabled for --site-per-process
+ // because cross-process subframe navigations still have a main frame
+ // PageTransition.
+ if (!use_site_per_process)
+ DCHECK(PageTransitionIsMainFrame(params.transition));
+ frame_tree->OnFirstNavigationAfterSwap(params.frame_id);
+ }
+
+ // When using --site-per-process, look up the FrameTreeNode ID that the
+ // renderer-specific frame ID corresponds to.
+ int64 frame_tree_node_id = frame_tree->root()->frame_tree_node_id();
+ if (use_site_per_process) {
+ frame_tree_node_id =
+ render_frame_host->frame_tree_node()->frame_tree_node_id();
+ DCHECK_EQ(params.frame_id,
+ render_frame_host->frame_tree_node()->frame_id());
+
+ // TODO(creis): In the short term, cross-process subframe navigations are
+ // happening in the pending RenderViewHost's top-level frame. (We need to
+ // both mirror the frame tree and get the navigation to occur in the correct
+ // subframe to fix this.) Until then, we should check whether we have a
+ // pending NavigationEntry with a frame ID and if so, treat the
+ // cross-process "main frame" navigation as a subframe navigation. This
+ // limits us to a single cross-process subframe per RVH, and it affects
+ // NavigateToEntry, NavigatorImpl::DidStartProvisionalLoad, and
+ // OnDidFinishLoad.
+ NavigationEntryImpl* pending_entry =
+ NavigationEntryImpl::FromNavigationEntry(
+ controller_->GetPendingEntry());
+ int root_ftn_id = frame_tree->root()->frame_tree_node_id();
+ if (pending_entry &&
+ pending_entry->frame_tree_node_id() != -1 &&
+ pending_entry->frame_tree_node_id() != root_ftn_id) {
+ params.transition = PAGE_TRANSITION_AUTO_SUBFRAME;
+ frame_tree_node_id = pending_entry->frame_tree_node_id();
+ }
+ }
+
+ if (PageTransitionIsMainFrame(params.transition)) {
+ // When overscroll navigation gesture is enabled, a screenshot of the page
+ // in its current state is taken so that it can be used during the
+ // nav-gesture. It is necessary to take the screenshot here, before calling
+ // RenderFrameHostManager::DidNavigateMainFrame, because that can change
+ // WebContents::GetRenderViewHost to return the new host, instead of the one
+ // that may have just been swapped out.
+ if (delegate_ && delegate_->CanOverscrollContent())
+ controller_->TakeScreenshot();
+
+ if (!use_site_per_process)
+ GetRenderManager(render_frame_host)->DidNavigateMainFrame(rvh);
+ }
+
+ // When using --site-per-process, we notify the RFHM for all navigations,
+ // not just main frame navigations.
+ if (use_site_per_process) {
+ FrameTreeNode* frame = frame_tree->FindByID(frame_tree_node_id);
+ // TODO(creis): Rename to DidNavigateFrame.
+ frame->render_manager()->DidNavigateMainFrame(rvh);
+ }
+
+ // Update the site of the SiteInstance if it doesn't have one yet, unless
+ // assigning a site is not necessary for this URL. In that case, the
+ // SiteInstance can still be considered unused until a navigation to a real
+ // page.
+ SiteInstanceImpl* site_instance =
+ static_cast<SiteInstanceImpl*>(render_frame_host->GetSiteInstance());
+ if (!site_instance->HasSite() &&
+ ShouldAssignSiteForURL(params.url)) {
+ site_instance->SetSite(params.url);
+ }
+
+ // Need to update MIME type here because it's referred to in
+ // UpdateNavigationCommands() called by RendererDidNavigate() to
+ // determine whether or not to enable the encoding menu.
+ // It's updated only for the main frame. For a subframe,
+ // RenderView::UpdateURL does not set params.contents_mime_type.
+ // (see http://code.google.com/p/chromium/issues/detail?id=2929 )
+ // TODO(jungshik): Add a test for the encoding menu to avoid
+ // regressing it again.
+ // TODO(nasko): Verify the correctness of the above comment, since some of the
+ // code doesn't exist anymore. Also, move this code in the
+ // PageTransitionIsMainFrame code block above.
+ if (PageTransitionIsMainFrame(params.transition) && delegate_)
+ delegate_->SetMainFrameMimeType(params.contents_mime_type);
+
+ LoadCommittedDetails details;
+ bool did_navigate = controller_->RendererDidNavigate(rvh, params, &details);
+
+ // For now, keep track of each frame's URL in its FrameTreeNode. This lets
+ // us estimate our process count for implementing OOP iframes.
+ // TODO(creis): Remove this when we track which pages commit in each frame.
+ frame_tree->SetFrameUrl(params.frame_id, params.url);
+
+ // Send notification about committed provisional loads. This notification is
+ // different from the NAV_ENTRY_COMMITTED notification which doesn't include
+ // the actual URL navigated to and isn't sent for AUTO_SUBFRAME navigations.
+ if (details.type != NAVIGATION_TYPE_NAV_IGNORE && delegate_) {
+ // For AUTO_SUBFRAME navigations, an event for the main frame is generated
+ // that is not recorded in the navigation history. For the purpose of
+ // tracking navigation events, we treat this event as a sub frame navigation
+ // event.
+ bool is_main_frame = did_navigate ? details.is_main_frame : false;
+ PageTransition transition_type = params.transition;
+ // Whether or not a page transition was triggered by going backward or
+ // forward in the history is only stored in the navigation controller's
+ // entry list.
+ if (did_navigate &&
+ (controller_->GetLastCommittedEntry()->GetTransitionType() &
+ PAGE_TRANSITION_FORWARD_BACK)) {
+ transition_type = PageTransitionFromInt(
+ params.transition | PAGE_TRANSITION_FORWARD_BACK);
+ }
+
+ delegate_->DidCommitProvisionalLoad(params.frame_id,
+ params.frame_unique_name,
+ is_main_frame,
+ params.url,
+ transition_type,
+ render_frame_host);
+ }
+
+ if (!did_navigate)
+ return; // No navigation happened.
+
+ // DO NOT ADD MORE STUFF TO THIS FUNCTION! Your component should either listen
+ // for the appropriate notification (best) or you can add it to
+ // DidNavigateMainFramePostCommit / DidNavigateAnyFramePostCommit (only if
+ // necessary, please).
+
+ // Run post-commit tasks.
+ if (delegate_) {
+ if (details.is_main_frame)
+ delegate_->DidNavigateMainFramePostCommit(details, params);
+
+ delegate_->DidNavigateAnyFramePostCommit(
+ render_frame_host, details, params);
+ }
+}
+
+bool NavigatorImpl::ShouldAssignSiteForURL(const GURL& url) {
+ // about:blank should not "use up" a new SiteInstance. The SiteInstance can
+ // still be used for a normal web site.
+ if (url == GURL(kAboutBlankURL))
+ return false;
+
+ // The embedder will then have the opportunity to determine if the URL
+ // should "use up" the SiteInstance.
+ return GetContentClient()->browser()->ShouldAssignSiteForURL(url);
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698