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

Side by Side Diff: content/browser/web_contents/web_contents_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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/web_contents/web_contents_impl.h" 5 #include "content/browser/web_contents/web_contents_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 2045 matching lines...) Expand 10 before | Expand all | Expand 10 after
2056 RenderFrameHostImpl* render_frame_host, 2056 RenderFrameHostImpl* render_frame_host,
2057 const GURL& validated_target_url) { 2057 const GURL& validated_target_url) {
2058 // Notify observers about the provisional change in the main frame URL. 2058 // Notify observers about the provisional change in the main frame URL.
2059 FOR_EACH_OBSERVER( 2059 FOR_EACH_OBSERVER(
2060 WebContentsObserver, 2060 WebContentsObserver,
2061 observers_, 2061 observers_,
2062 ProvisionalChangeToMainFrameUrl(validated_target_url, 2062 ProvisionalChangeToMainFrameUrl(validated_target_url,
2063 render_frame_host)); 2063 render_frame_host));
2064 } 2064 }
2065 2065
2066 void WebContentsImpl::DidCommitProvisionalLoad(
2067 int64 frame_id,
2068 const base::string16& frame_unique_name,
2069 bool is_main_frame,
2070 const GURL& url,
2071 PageTransition transition_type,
2072 RenderFrameHostImpl* render_frame_host) {
2073 // Notify observers about the commit of the provisional load.
2074 FOR_EACH_OBSERVER(
2075 WebContentsObserver,
2076 observers_,
2077 DidCommitProvisionalLoadForFrame(frame_id,
2078 frame_unique_name,
2079 is_main_frame,
2080 url,
2081 transition_type,
2082 render_frame_host->render_view_host()));
2083 }
2084
2085 void WebContentsImpl::DidNavigateMainFramePostCommit(
2086 const LoadCommittedDetails& details,
2087 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) {
2088 if (details.is_navigation_to_different_page()) {
2089 // Clear the status bubble. This is a workaround for a bug where WebKit
2090 // doesn't let us know that the cursor left an element during a
2091 // transition (this is also why the mouse cursor remains as a hand after
2092 // clicking on a link); see bugs 1184641 and 980803. We don't want to
2093 // clear the bubble when a user navigates to a named anchor in the same
2094 // page.
2095 UpdateTargetURL(details.entry->GetPageID(), GURL());
2096 }
2097
2098 if (!details.is_in_page) {
2099 // Once the main frame is navigated, we're no longer considered to have
2100 // displayed insecure content.
2101 displayed_insecure_content_ = false;
2102 SSLManager::NotifySSLInternalStateChanged(
2103 GetController().GetBrowserContext());
2104 }
2105
2106 // Notify observers about navigation.
2107 FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2108 DidNavigateMainFrame(details, params));
2109
2110 if (delegate_) {
2111 delegate_->DidNavigateMainFramePostCommit(this);
2112 view_->SetOverscrollControllerEnabled(delegate_->CanOverscrollContent());
2113 }
2114 }
2115
2116 void WebContentsImpl::DidNavigateAnyFramePostCommit(
2117 RenderFrameHostImpl* render_frame_host,
2118 const LoadCommittedDetails& details,
2119 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) {
2120 // If we navigate off the page, close all JavaScript dialogs.
2121 if (dialog_manager_ && !details.is_in_page)
2122 dialog_manager_->CancelActiveAndPendingDialogs(this);
2123
2124 // Notify observers about navigation.
2125 FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2126 DidNavigateAnyFrame(details, params));
2127 }
2128
2129 void WebContentsImpl::SetMainFrameMimeType(const std::string& mime_type) {
2130 contents_mime_type_ = mime_type;
2131 }
2132
2133 bool WebContentsImpl::CanOverscrollContent() {
2134 if (delegate_)
2135 return delegate_->CanOverscrollContent();
2136
2137 return false;
2138 }
2139
2066 void WebContentsImpl::OnDidLoadResourceFromMemoryCache( 2140 void WebContentsImpl::OnDidLoadResourceFromMemoryCache(
2067 const GURL& url, 2141 const GURL& url,
2068 const std::string& security_info, 2142 const std::string& security_info,
2069 const std::string& http_method, 2143 const std::string& http_method,
2070 const std::string& mime_type, 2144 const std::string& mime_type,
2071 ResourceType::Type resource_type) { 2145 ResourceType::Type resource_type) {
2072 base::StatsCounter cache("WebKit.CacheHit"); 2146 base::StatsCounter cache("WebKit.CacheHit");
2073 cache.Increment(); 2147 cache.Increment();
2074 2148
2075 // Send out a notification that we loaded a resource from our memory cache. 2149 // Send out a notification that we loaded a resource from our memory cache.
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
2500 2574
2501 // TODO(avi): Remove. http://crbug.com/170921 2575 // TODO(avi): Remove. http://crbug.com/170921
2502 int type = is_loading ? NOTIFICATION_LOAD_START : NOTIFICATION_LOAD_STOP; 2576 int type = is_loading ? NOTIFICATION_LOAD_START : NOTIFICATION_LOAD_STOP;
2503 NotificationDetails det = NotificationService::NoDetails(); 2577 NotificationDetails det = NotificationService::NoDetails();
2504 if (details) 2578 if (details)
2505 det = Details<LoadNotificationDetails>(details); 2579 det = Details<LoadNotificationDetails>(details);
2506 NotificationService::current()->Notify( 2580 NotificationService::current()->Notify(
2507 type, Source<NavigationController>(&controller_), det); 2581 type, Source<NavigationController>(&controller_), det);
2508 } 2582 }
2509 2583
2510 void WebContentsImpl::DidNavigateMainFramePostCommit(
2511 const LoadCommittedDetails& details,
2512 const ViewHostMsg_FrameNavigate_Params& params) {
2513 if (details.is_navigation_to_different_page()) {
2514 // Clear the status bubble. This is a workaround for a bug where WebKit
2515 // doesn't let us know that the cursor left an element during a
2516 // transition (this is also why the mouse cursor remains as a hand after
2517 // clicking on a link); see bugs 1184641 and 980803. We don't want to
2518 // clear the bubble when a user navigates to a named anchor in the same
2519 // page.
2520 UpdateTargetURL(details.entry->GetPageID(), GURL());
2521 }
2522
2523 if (!details.is_in_page) {
2524 // Once the main frame is navigated, we're no longer considered to have
2525 // displayed insecure content.
2526 displayed_insecure_content_ = false;
2527 SSLManager::NotifySSLInternalStateChanged(
2528 GetController().GetBrowserContext());
2529 }
2530
2531 // Notify observers about navigation.
2532 FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2533 DidNavigateMainFrame(details, params));
2534 }
2535
2536 void WebContentsImpl::DidNavigateAnyFramePostCommit(
2537 RenderViewHost* render_view_host,
2538 const LoadCommittedDetails& details,
2539 const ViewHostMsg_FrameNavigate_Params& params) {
2540 // If we navigate off the page, close all JavaScript dialogs.
2541 if (dialog_manager_ && !details.is_in_page)
2542 dialog_manager_->CancelActiveAndPendingDialogs(this);
2543
2544 // Notify observers about navigation.
2545 FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2546 DidNavigateAnyFrame(details, params));
2547 }
2548
2549 bool WebContentsImpl::ShouldAssignSiteForURL(const GURL& url) {
2550 // about:blank should not "use up" a new SiteInstance. The SiteInstance can
2551 // still be used for a normal web site.
2552 if (url == GURL(kAboutBlankURL))
2553 return false;
2554
2555 // The embedder will then have the opportunity to determine if the URL
2556 // should "use up" the SiteInstance.
2557 return GetContentClient()->browser()->ShouldAssignSiteForURL(url);
2558 }
2559
2560 void WebContentsImpl::UpdateMaxPageIDIfNecessary(RenderViewHost* rvh) { 2584 void WebContentsImpl::UpdateMaxPageIDIfNecessary(RenderViewHost* rvh) {
2561 // If we are creating a RVH for a restored controller, then we need to make 2585 // If we are creating a RVH for a restored controller, then we need to make
2562 // sure the RenderView starts with a next_page_id_ larger than the number 2586 // sure the RenderView starts with a next_page_id_ larger than the number
2563 // of restored entries. This must be called before the RenderView starts 2587 // of restored entries. This must be called before the RenderView starts
2564 // navigating (to avoid a race between the browser updating max_page_id and 2588 // navigating (to avoid a race between the browser updating max_page_id and
2565 // the renderer updating next_page_id_). Because of this, we only call this 2589 // the renderer updating next_page_id_). Because of this, we only call this
2566 // from CreateRenderView and allow that to notify the RenderView for us. 2590 // from CreateRenderView and allow that to notify the RenderView for us.
2567 int max_restored_page_id = controller_.GetMaxRestoredPageID(); 2591 int max_restored_page_id = controller_.GetMaxRestoredPageID();
2568 if (max_restored_page_id > 2592 if (max_restored_page_id >
2569 GetMaxPageIDForSiteInstance(rvh->GetSiteInstance())) 2593 GetMaxPageIDForSiteInstance(rvh->GetSiteInstance()))
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
2807 observers_, 2831 observers_,
2808 RenderProcessGone(GetCrashedStatus())); 2832 RenderProcessGone(GetCrashedStatus()));
2809 } 2833 }
2810 2834
2811 void WebContentsImpl::RenderViewDeleted(RenderViewHost* rvh) { 2835 void WebContentsImpl::RenderViewDeleted(RenderViewHost* rvh) {
2812 ClearPowerSaveBlockers(rvh); 2836 ClearPowerSaveBlockers(rvh);
2813 GetRenderManager()->RenderViewDeleted(rvh); 2837 GetRenderManager()->RenderViewDeleted(rvh);
2814 FOR_EACH_OBSERVER(WebContentsObserver, observers_, RenderViewDeleted(rvh)); 2838 FOR_EACH_OBSERVER(WebContentsObserver, observers_, RenderViewDeleted(rvh));
2815 } 2839 }
2816 2840
2817 void WebContentsImpl::DidNavigate(
2818 RenderViewHost* rvh,
2819 const ViewHostMsg_FrameNavigate_Params& orig_params) {
2820 ViewHostMsg_FrameNavigate_Params params(orig_params);
2821 bool use_site_per_process =
2822 CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess);
2823 if (frame_tree_.IsFirstNavigationAfterSwap()) {
2824 // First navigation should be a main frame navigation.
2825 // TODO(creis): This DCHECK is currently disabled for --site-per-process
2826 // because cross-process subframe navigations still have a main frame
2827 // PageTransition.
2828 if (!use_site_per_process)
2829 DCHECK(PageTransitionIsMainFrame(params.transition));
2830 frame_tree_.OnFirstNavigationAfterSwap(params.frame_id);
2831 }
2832
2833 // When using --site-per-process, look up the FrameTreeNode ID that the
2834 // renderer-specific frame ID corresponds to.
2835 int64 frame_tree_node_id = frame_tree_.root()->frame_tree_node_id();
2836 if (use_site_per_process) {
2837 FrameTreeNode* source_node = frame_tree_.FindByFrameID(params.frame_id);
2838 if (source_node)
2839 frame_tree_node_id = source_node->frame_tree_node_id();
2840
2841 // TODO(creis): In the short term, cross-process subframe navigations are
2842 // happening in the pending RenderViewHost's top-level frame. (We need to
2843 // both mirror the frame tree and get the navigation to occur in the correct
2844 // subframe to fix this.) Until then, we should check whether we have a
2845 // pending NavigationEntry with a frame ID and if so, treat the
2846 // cross-process "main frame" navigation as a subframe navigation. This
2847 // limits us to a single cross-process subframe per RVH, and it affects
2848 // NavigateToEntry, NavigatorImpl::DidStartProvisionalLoad, and
2849 // OnDidFinishLoad.
2850 NavigationEntryImpl* pending_entry =
2851 NavigationEntryImpl::FromNavigationEntry(controller_.GetPendingEntry());
2852 int root_ftn_id = frame_tree_.root()->frame_tree_node_id();
2853 if (pending_entry &&
2854 pending_entry->frame_tree_node_id() != -1 &&
2855 pending_entry->frame_tree_node_id() != root_ftn_id) {
2856 params.transition = PAGE_TRANSITION_AUTO_SUBFRAME;
2857 frame_tree_node_id = pending_entry->frame_tree_node_id();
2858 }
2859 }
2860
2861 if (PageTransitionIsMainFrame(params.transition)) {
2862 // When overscroll navigation gesture is enabled, a screenshot of the page
2863 // in its current state is taken so that it can be used during the
2864 // nav-gesture. It is necessary to take the screenshot here, before calling
2865 // RenderFrameHostManager::DidNavigateMainFrame, because that can change
2866 // WebContents::GetRenderViewHost to return the new host, instead of the one
2867 // that may have just been swapped out.
2868 if (delegate_ && delegate_->CanOverscrollContent())
2869 controller_.TakeScreenshot();
2870
2871 if (!use_site_per_process)
2872 GetRenderManager()->DidNavigateMainFrame(rvh);
2873 }
2874
2875 // When using --site-per-process, we notify the RFHM for all navigations,
2876 // not just main frame navigations.
2877 if (use_site_per_process) {
2878 FrameTreeNode* frame = frame_tree_.FindByID(frame_tree_node_id);
2879 // TODO(creis): Rename to DidNavigateFrame.
2880 frame->render_manager()->DidNavigateMainFrame(rvh);
2881 }
2882
2883 // Update the site of the SiteInstance if it doesn't have one yet, unless
2884 // assigning a site is not necessary for this URL. In that case, the
2885 // SiteInstance can still be considered unused until a navigation to a real
2886 // page.
2887 if (!static_cast<SiteInstanceImpl*>(GetSiteInstance())->HasSite() &&
2888 ShouldAssignSiteForURL(params.url)) {
2889 static_cast<SiteInstanceImpl*>(GetSiteInstance())->SetSite(params.url);
2890 }
2891
2892 // Need to update MIME type here because it's referred to in
2893 // UpdateNavigationCommands() called by RendererDidNavigate() to
2894 // determine whether or not to enable the encoding menu.
2895 // It's updated only for the main frame. For a subframe,
2896 // RenderView::UpdateURL does not set params.contents_mime_type.
2897 // (see http://code.google.com/p/chromium/issues/detail?id=2929 )
2898 // TODO(jungshik): Add a test for the encoding menu to avoid
2899 // regressing it again.
2900 if (PageTransitionIsMainFrame(params.transition))
2901 contents_mime_type_ = params.contents_mime_type;
2902
2903 LoadCommittedDetails details;
2904 bool did_navigate = controller_.RendererDidNavigate(rvh, params, &details);
2905
2906 // For now, keep track of each frame's URL in its FrameTreeNode. This lets
2907 // us estimate our process count for implementing OOP iframes.
2908 // TODO(creis): Remove this when we track which pages commit in each frame.
2909 frame_tree_.SetFrameUrl(params.frame_id, params.url);
2910
2911 // Send notification about committed provisional loads. This notification is
2912 // different from the NAV_ENTRY_COMMITTED notification which doesn't include
2913 // the actual URL navigated to and isn't sent for AUTO_SUBFRAME navigations.
2914 if (details.type != NAVIGATION_TYPE_NAV_IGNORE) {
2915 // For AUTO_SUBFRAME navigations, an event for the main frame is generated
2916 // that is not recorded in the navigation history. For the purpose of
2917 // tracking navigation events, we treat this event as a sub frame navigation
2918 // event.
2919 bool is_main_frame = did_navigate ? details.is_main_frame : false;
2920 PageTransition transition_type = params.transition;
2921 // Whether or not a page transition was triggered by going backward or
2922 // forward in the history is only stored in the navigation controller's
2923 // entry list.
2924 if (did_navigate &&
2925 (controller_.GetLastCommittedEntry()->GetTransitionType() &
2926 PAGE_TRANSITION_FORWARD_BACK)) {
2927 transition_type = PageTransitionFromInt(
2928 params.transition | PAGE_TRANSITION_FORWARD_BACK);
2929 }
2930 // Notify observers about the commit of the provisional load.
2931 FOR_EACH_OBSERVER(WebContentsObserver, observers_,
2932 DidCommitProvisionalLoadForFrame(
2933 params.frame_id,
2934 params.frame_unique_name,
2935 is_main_frame,
2936 params.url,
2937 transition_type,
2938 rvh));
2939 }
2940
2941 if (!did_navigate)
2942 return; // No navigation happened.
2943
2944 // DO NOT ADD MORE STUFF TO THIS FUNCTION! Your component should either listen
2945 // for the appropriate notification (best) or you can add it to
2946 // DidNavigateMainFramePostCommit / DidNavigateAnyFramePostCommit (only if
2947 // necessary, please).
2948
2949 // Run post-commit tasks.
2950 if (details.is_main_frame) {
2951 DidNavigateMainFramePostCommit(details, params);
2952 if (delegate_) {
2953 delegate_->DidNavigateMainFramePostCommit(this);
2954 view_->SetOverscrollControllerEnabled(delegate_->CanOverscrollContent());
2955 }
2956 }
2957 DidNavigateAnyFramePostCommit(rvh, details, params);
2958 }
2959
2960 void WebContentsImpl::UpdateState(RenderViewHost* rvh, 2841 void WebContentsImpl::UpdateState(RenderViewHost* rvh,
2961 int32 page_id, 2842 int32 page_id,
2962 const PageState& page_state) { 2843 const PageState& page_state) {
2963 // Ensure that this state update comes from either the active RVH or one of 2844 // Ensure that this state update comes from either the active RVH or one of
2964 // the swapped out RVHs. We don't expect to hear from any other RVHs. 2845 // the swapped out RVHs. We don't expect to hear from any other RVHs.
2965 // TODO(nasko): This should go through RenderFrameHost. 2846 // TODO(nasko): This should go through RenderFrameHost.
2966 // TODO(creis): We can't update state for cross-process subframes until we 2847 // TODO(creis): We can't update state for cross-process subframes until we
2967 // have FrameNavigationEntries. Once we do, this should be a DCHECK. 2848 // have FrameNavigationEntries. Once we do, this should be a DCHECK.
2968 if (rvh != GetRenderViewHost() && 2849 if (rvh != GetRenderViewHost() &&
2969 !GetRenderManager()->IsRVHOnSwappedOutList( 2850 !GetRenderManager()->IsRVHOnSwappedOutList(
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after
3739 } 3620 }
3740 3621
3741 void WebContentsImpl::OnFrameRemoved( 3622 void WebContentsImpl::OnFrameRemoved(
3742 RenderViewHostImpl* render_view_host, 3623 RenderViewHostImpl* render_view_host,
3743 int64 frame_id) { 3624 int64 frame_id) {
3744 FOR_EACH_OBSERVER(WebContentsObserver, observers_, 3625 FOR_EACH_OBSERVER(WebContentsObserver, observers_,
3745 FrameDetached(render_view_host, frame_id)); 3626 FrameDetached(render_view_host, frame_id));
3746 } 3627 }
3747 3628
3748 } // namespace content 3629 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698