diff options
Diffstat (limited to 'content')
-rw-r--r-- | content/browser/renderer_host/test_render_view_host.cc | 6 | ||||
-rw-r--r-- | content/browser/renderer_host/test_render_view_host.h | 8 | ||||
-rw-r--r-- | content/browser/web_contents/navigation_controller_impl.cc | 18 | ||||
-rw-r--r-- | content/browser/web_contents/navigation_controller_impl_unittest.cc | 49 | ||||
-rw-r--r-- | content/browser/web_contents/navigation_entry_impl.cc | 2 | ||||
-rw-r--r-- | content/browser/web_contents/navigation_entry_impl.h | 16 | ||||
-rw-r--r-- | content/browser/web_contents/web_contents_impl.cc | 17 | ||||
-rw-r--r-- | content/common/view_messages.h | 9 | ||||
-rw-r--r-- | content/public/browser/navigation_controller.cc | 7 | ||||
-rw-r--r-- | content/public/browser/navigation_controller.h | 8 | ||||
-rw-r--r-- | content/public/renderer/navigation_state.cc | 4 | ||||
-rw-r--r-- | content/public/renderer/navigation_state.h | 21 | ||||
-rw-r--r-- | content/renderer/render_view_impl.cc | 14 | ||||
-rw-r--r-- | content/shell/webkit_test_controller.cc | 19 |
14 files changed, 178 insertions, 20 deletions
diff --git a/content/browser/renderer_host/test_render_view_host.cc b/content/browser/renderer_host/test_render_view_host.cc index cff1d21..0e1792a 100644 --- a/content/browser/renderer_host/test_render_view_host.cc +++ b/content/browser/renderer_host/test_render_view_host.cc @@ -241,6 +241,7 @@ TestRenderViewHost::TestRenderViewHost( render_view_created_(false), delete_counter_(NULL), simulate_fetch_via_proxy_(false), + simulate_history_list_was_cleared_(false), contents_mime_type_("text/html") { // For normal RenderViewHosts, this is freed when |Shutdown()| is // called. For TestRenderViewHost, the view is explicitly @@ -322,6 +323,7 @@ void TestRenderViewHost::SendNavigateWithParameters( params.socket_address.set_host("2001:db8::1"); params.socket_address.set_port(80); params.was_fetched_via_proxy = simulate_fetch_via_proxy_; + params.history_list_was_cleared = simulate_history_list_was_cleared_; params.content_state = webkit_glue::CreateHistoryStateForURL(GURL(url)); params.original_request_url = original_request_url; @@ -362,6 +364,10 @@ void TestRenderViewHost::set_simulate_fetch_via_proxy(bool proxy) { simulate_fetch_via_proxy_ = proxy; } +void TestRenderViewHost::set_simulate_history_list_was_cleared(bool cleared) { + simulate_history_list_was_cleared_ = cleared; +} + RenderViewHostImplTestHarness::RenderViewHostImplTestHarness() { } diff --git a/content/browser/renderer_host/test_render_view_host.h b/content/browser/renderer_host/test_render_view_host.h index 4251acf..a6ec555 100644 --- a/content/browser/renderer_host/test_render_view_host.h +++ b/content/browser/renderer_host/test_render_view_host.h @@ -284,6 +284,11 @@ class TestRenderViewHost // False by default. void set_simulate_fetch_via_proxy(bool proxy); + // If set, navigations will appear to have cleared the history list in the + // RenderView (ViewHostMsg_FrameNavigate_Params::history_list_was_cleared). + // False by default. + void set_simulate_history_list_was_cleared(bool cleared); + // RenderViewHost overrides -------------------------------------------------- virtual bool CreateRenderView(const string16& frame_name, @@ -319,6 +324,9 @@ class TestRenderViewHost // See set_simulate_fetch_via_proxy() above. bool simulate_fetch_via_proxy_; + // See set_simulate_history_list_was_cleared() above. + bool simulate_history_list_was_cleared_; + // See SetContentsMimeType() above. std::string contents_mime_type_; diff --git a/content/browser/web_contents/navigation_controller_impl.cc b/content/browser/web_contents/navigation_controller_impl.cc index 6051efe..f7c8215 100644 --- a/content/browser/web_contents/navigation_controller_impl.cc +++ b/content/browser/web_contents/navigation_controller_impl.cc @@ -659,6 +659,7 @@ void NavigationControllerImpl::LoadURLWithParams(const LoadURLParams& params) { browser_context_)); if (params.is_cross_site_redirect) entry->set_should_replace_entry(true); + entry->set_should_clear_history_list(params.should_clear_history_list); entry->SetIsOverridingUserAgent(override); entry->set_transferred_global_request_id( params.transferred_global_request_id); @@ -781,6 +782,10 @@ bool NavigationControllerImpl::RendererDidNavigate( // the renderer. active_entry->set_is_renderer_initiated(false); + // Once committed, we no longer need to track whether the session history was + // cleared. Navigating to this entry again shouldn't clear it again. + active_entry->set_should_clear_history_list(false); + // The active entry's SiteInstance should match our SiteInstance. CHECK(active_entry->site_instance() == web_contents_->GetSiteInstance()); @@ -843,6 +848,9 @@ NavigationType NavigationControllerImpl::ClassifyNavigation( return NAVIGATION_TYPE_NEW_SUBFRAME; } + // We only clear the session history when navigating to a new page. + DCHECK(!params.history_list_was_cleared); + // Now we know that the notification is for an existing page. Find that entry. int existing_entry_index = GetEntryIndexWithPageID( web_contents_->GetSiteInstance(), @@ -988,6 +996,16 @@ void NavigationControllerImpl::RendererDidNavigateToNewPage( new_entry->SetOriginalRequestURL(params.original_request_url); new_entry->SetIsOverridingUserAgent(params.is_overriding_user_agent); + DCHECK(!params.history_list_was_cleared || !replace_entry); + // The browser requested to clear the session history when it initiated the + // navigation. Now we know that the renderer has updated its state accordingly + // and it is safe to also clear the browser side history. + if (params.history_list_was_cleared) { + DiscardNonCommittedEntriesInternal(); + entries_.clear(); + last_committed_entry_index_ = -1; + } + InsertOrReplaceEntry(new_entry, replace_entry); } diff --git a/content/browser/web_contents/navigation_controller_impl_unittest.cc b/content/browser/web_contents/navigation_controller_impl_unittest.cc index a8433e7..1442be1 100644 --- a/content/browser/web_contents/navigation_controller_impl_unittest.cc +++ b/content/browser/web_contents/navigation_controller_impl_unittest.cc @@ -3325,6 +3325,55 @@ TEST_F(NavigationControllerTest, MAYBE_PurgeScreenshot) { } } +// Test that the navigation controller clears its session history when a +// navigation commits with the clear history list flag set. +TEST_F(NavigationControllerTest, ClearHistoryList) { + const GURL url1("http://foo1"); + const GURL url2("http://foo2"); + const GURL url3("http://foo3"); + const GURL url4("http://foo4"); + + NavigationControllerImpl& controller = controller_impl(); + + // Create a session history with three entries, second entry is active. + NavigateAndCommit(url1); + NavigateAndCommit(url2); + NavigateAndCommit(url3); + controller.GoBack(); + contents()->CommitPendingNavigation(); + EXPECT_EQ(3, controller.GetEntryCount()); + EXPECT_EQ(1, controller.GetCurrentEntryIndex()); + + // Create a new pending navigation, and indicate that the session history + // should be cleared. + NavigationController::LoadURLParams params(url4); + params.should_clear_history_list = true; + controller.LoadURLWithParams(params); + + // Verify that the pending entry correctly indicates that the session history + // should be cleared. + NavigationEntryImpl* entry = + NavigationEntryImpl::FromNavigationEntry( + controller.GetPendingEntry()); + ASSERT_TRUE(entry); + EXPECT_TRUE(entry->should_clear_history_list()); + + // Assume that the RV correctly cleared its history and commit the navigation. + static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost())-> + set_simulate_history_list_was_cleared(true); + contents()->CommitPendingNavigation(); + + // Verify that the NavigationController's session history was correctly + // cleared. + EXPECT_EQ(1, controller.GetEntryCount()); + EXPECT_EQ(0, controller.GetCurrentEntryIndex()); + EXPECT_EQ(0, controller.GetLastCommittedEntryIndex()); + EXPECT_EQ(-1, controller.GetPendingEntryIndex()); + EXPECT_FALSE(controller.CanGoBack()); + EXPECT_FALSE(controller.CanGoForward()); + EXPECT_EQ(url4, controller.GetActiveEntry()->GetURL()); +} + /* TODO(brettw) These test pass on my local machine but fail on the XP buildbot (but not Vista) cleaning up the directory after they run. This should be fixed. diff --git a/content/browser/web_contents/navigation_entry_impl.cc b/content/browser/web_contents/navigation_entry_impl.cc index b3b6f78..b904acf 100644 --- a/content/browser/web_contents/navigation_entry_impl.cc +++ b/content/browser/web_contents/navigation_entry_impl.cc @@ -50,6 +50,7 @@ NavigationEntryImpl::NavigationEntryImpl() is_overriding_user_agent_(false), is_renderer_initiated_(false), should_replace_entry_(false), + should_clear_history_list_(false), can_load_local_resources_(false) { } @@ -76,6 +77,7 @@ NavigationEntryImpl::NavigationEntryImpl(SiteInstanceImpl* instance, is_overriding_user_agent_(false), is_renderer_initiated_(is_renderer_initiated), should_replace_entry_(false), + should_clear_history_list_(false), can_load_local_resources_(false) { } diff --git a/content/browser/web_contents/navigation_entry_impl.h b/content/browser/web_contents/navigation_entry_impl.h index c5d8c49..c956867 100644 --- a/content/browser/web_contents/navigation_entry_impl.h +++ b/content/browser/web_contents/navigation_entry_impl.h @@ -190,6 +190,15 @@ class CONTENT_EXPORT NavigationEntryImpl return screenshot_; } + // Whether this (pending) navigation should clear the session history. Resets + // to false after commit. + bool should_clear_history_list() const { + return should_clear_history_list_; + } + void set_should_clear_history_list(bool should_clear_history_list) { + should_clear_history_list_ = should_clear_history_list; + } + private: // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING // Session/Tab restore save portions of this class so that it can be recreated @@ -275,6 +284,13 @@ class CONTENT_EXPORT NavigationEntryImpl // doing the redirect). bool should_replace_entry_; + // This is set to true when this entry's navigation should clear the session + // history both on the renderer and browser side. The browser side history + // won't be cleared until the renderer has committed this navigation. This + // entry is not persisted by the session restore system, as it is always + // reset to false after commit. + bool should_clear_history_list_; + // Set when this entry should be able to access local file:// resources. This // value is not needed after the entry commits and is not persisted. bool can_load_local_resources_; diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 7ba9ba4..78e728f 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -199,9 +199,20 @@ void MakeNavigateParams(const NavigationEntryImpl& entry, NavigationController::ReloadType reload_type, ViewMsg_Navigate_Params* params) { params->page_id = entry.GetPageID(); - params->pending_history_list_offset = controller.GetIndexOfEntry(&entry); - params->current_history_list_offset = controller.GetLastCommittedEntryIndex(); - params->current_history_list_length = controller.GetEntryCount(); + params->should_clear_history_list = entry.should_clear_history_list(); + if (entry.should_clear_history_list()) { + // Set the history list related parameters to the same values a + // NavigationController would return before its first navigation. This will + // fully clear the RenderView's view of the session history. + params->pending_history_list_offset = -1; + params->current_history_list_offset = -1; + params->current_history_list_length = 0; + } else { + params->pending_history_list_offset = controller.GetIndexOfEntry(&entry); + params->current_history_list_offset = + controller.GetLastCommittedEntryIndex(); + params->current_history_list_length = controller.GetEntryCount(); + } if (!entry.GetBaseURLForDataURL().is_empty()) { params->base_url_for_data_url = entry.GetBaseURLForDataURL(); params->history_url_for_data_url = entry.GetVirtualURL(); diff --git a/content/common/view_messages.h b/content/common/view_messages.h index 575d481..adc35cf 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -421,6 +421,10 @@ IPC_STRUCT_BEGIN_WITH_PARENT(ViewHostMsg_FrameNavigate_Params, // User agent override used to navigate. IPC_STRUCT_MEMBER(bool, is_overriding_user_agent) + + // Notifies the browser that for this navigation, the session history was + // successfully cleared. + IPC_STRUCT_MEMBER(bool, history_list_was_cleared) IPC_STRUCT_END() IPC_STRUCT_BEGIN(ViewHostMsg_OpenURL_Params) @@ -572,6 +576,11 @@ IPC_STRUCT_BEGIN(ViewMsg_Navigate_Params) IPC_STRUCT_MEMBER(int, current_history_list_offset) IPC_STRUCT_MEMBER(int, current_history_list_length) + // Informs the RenderView the session history should be cleared. In that + // case, the RenderView needs to notify the browser that the clearing was + // succesful when the navigation commits. + IPC_STRUCT_MEMBER(bool, should_clear_history_list) + // The URL to load. IPC_STRUCT_MEMBER(GURL, url) diff --git a/content/public/browser/navigation_controller.cc b/content/public/browser/navigation_controller.cc index 5fc56dc..fa1dc1b 100644 --- a/content/public/browser/navigation_controller.cc +++ b/content/public/browser/navigation_controller.cc @@ -16,7 +16,8 @@ NavigationController::LoadURLParams::LoadURLParams(const GURL& url) override_user_agent(UA_OVERRIDE_INHERIT), browser_initiated_post_data(NULL), can_load_local_resources(false), - is_cross_site_redirect(false) { + is_cross_site_redirect(false), + should_clear_history_list(false) { } NavigationController::LoadURLParams::~LoadURLParams() { @@ -35,7 +36,8 @@ NavigationController::LoadURLParams::LoadURLParams( base_url_for_data_url(other.base_url_for_data_url), virtual_url_for_data_url(other.virtual_url_for_data_url), browser_initiated_post_data(other.browser_initiated_post_data), - is_cross_site_redirect(false) { + is_cross_site_redirect(false), + should_clear_history_list(false) { } NavigationController::LoadURLParams& @@ -53,6 +55,7 @@ NavigationController::LoadURLParams::operator=( virtual_url_for_data_url = other.virtual_url_for_data_url; browser_initiated_post_data = other.browser_initiated_post_data; is_cross_site_redirect = other.is_cross_site_redirect; + should_clear_history_list = other.should_clear_history_list; return *this; } diff --git a/content/public/browser/navigation_controller.h b/content/public/browser/navigation_controller.h index 1cb18ec..5109301 100644 --- a/content/public/browser/navigation_controller.h +++ b/content/public/browser/navigation_controller.h @@ -159,6 +159,14 @@ class NavigationController { // navigated. This is currently only used in tests. std::string frame_name; + // Indicates that during this navigation, the session history should be + // cleared such that the resulting page is the first and only entry of the + // session history. + // + // The clearing is done asynchronously, and completes when this navigation + // commits. + bool should_clear_history_list; + explicit LoadURLParams(const GURL& url); ~LoadURLParams(); diff --git a/content/public/renderer/navigation_state.cc b/content/public/renderer/navigation_state.cc index 9208efa..5745a2b 100644 --- a/content/public/renderer/navigation_state.cc +++ b/content/public/renderer/navigation_state.cc @@ -9,12 +9,14 @@ namespace content { NavigationState::NavigationState(content::PageTransition transition_type, bool is_content_initiated, int32 pending_page_id, - int pending_history_list_offset) + int pending_history_list_offset, + bool history_list_was_cleared) : transition_type_(transition_type), request_committed_(false), is_content_initiated_(is_content_initiated), pending_page_id_(pending_page_id), pending_history_list_offset_(pending_history_list_offset), + history_list_was_cleared_(history_list_was_cleared), was_within_same_page_(false), transferred_request_child_id_(-1), transferred_request_request_id_(-1), diff --git a/content/public/renderer/navigation_state.h b/content/public/renderer/navigation_state.h index ba9f438..01f92a0 100644 --- a/content/public/renderer/navigation_state.h +++ b/content/public/renderer/navigation_state.h @@ -22,13 +22,18 @@ class CONTENT_EXPORT NavigationState { static NavigationState* CreateBrowserInitiated( int32 pending_page_id, int pending_history_list_offset, + bool history_list_was_cleared, content::PageTransition transition_type) { - return new NavigationState(transition_type, false, pending_page_id, - pending_history_list_offset); + return new NavigationState(transition_type, + false, + pending_page_id, + pending_history_list_offset, + history_list_was_cleared); } static NavigationState* CreateContentInitiated() { - return new NavigationState(content::PAGE_TRANSITION_LINK, true, -1, -1); + return new NavigationState( + content::PAGE_TRANSITION_LINK, true, -1, -1, false); } // Contains the page_id for this navigation or -1 if there is none yet. @@ -40,6 +45,12 @@ class CONTENT_EXPORT NavigationState { return pending_history_list_offset_; } + // If pending_page_id() is not -1, then this returns true if the session + // history was cleared during this navigation. + bool history_list_was_cleared() const { + return history_list_was_cleared_; + } + // Contains the transition type that the browser specified when it // initiated the load. content::PageTransition transition_type() const { return transition_type_; } @@ -91,13 +102,15 @@ class CONTENT_EXPORT NavigationState { NavigationState(content::PageTransition transition_type, bool is_content_initiated, int32 pending_page_id, - int pending_history_list_offset); + int pending_history_list_offset, + bool history_list_was_cleared); content::PageTransition transition_type_; bool request_committed_; bool is_content_initiated_; int32 pending_page_id_; int pending_history_list_offset_; + bool history_list_was_cleared_; bool was_within_same_page_; int transferred_request_child_id_; diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index ab7bde9..6f0a219 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -1164,6 +1164,11 @@ void RenderViewImpl::OnNavigate(const ViewMsg_Navigate_Params& params) { SetSwappedOut(false); } + if (params.should_clear_history_list) { + CHECK_EQ(params.pending_history_list_offset, -1); + CHECK_EQ(params.current_history_list_offset, -1); + CHECK_EQ(params.current_history_list_length, 0); + } history_list_offset_ = params.current_history_list_offset; history_list_length_ = params.current_history_list_length; if (history_list_length_ >= 0) @@ -1746,6 +1751,9 @@ void RenderViewImpl::UpdateURL(WebFrame* frame) { // Track the URL of the original request. params.original_request_url = original_request.url(); + params.history_list_was_cleared = + navigation_state->history_list_was_cleared(); + // Save some histogram data so we can compute the average memory used per // page load of the glyphs. UMA_HISTOGRAM_COUNTS_10000("Memory.GlyphPagesPerLoad", @@ -1767,6 +1775,9 @@ void RenderViewImpl::UpdateURL(WebFrame* frame) { else params.transition = PAGE_TRANSITION_AUTO_SUBFRAME; + DCHECK(!navigation_state->history_list_was_cleared()); + params.history_list_was_cleared = false; + Send(new ViewHostMsg_FrameNavigate(routing_id_, params)); } @@ -3295,6 +3306,7 @@ NavigationState* RenderViewImpl::CreateNavigationStateFromPending() { navigation_state = NavigationState::CreateBrowserInitiated( params.page_id, params.pending_history_list_offset, + params.should_clear_history_list, params.transition); navigation_state->set_transferred_request_child_id( params.transferred_request_child_id); @@ -3492,6 +3504,8 @@ void RenderViewImpl::didFailProvisionalLoad(WebFrame* frame, navigation_state->pending_page_id(); pending_navigation_params_->pending_history_list_offset = navigation_state->pending_history_list_offset(); + pending_navigation_params_->should_clear_history_list = + navigation_state->history_list_was_cleared(); pending_navigation_params_->transition = navigation_state->transition_type(); pending_navigation_params_->request_time = diff --git a/content/shell/webkit_test_controller.cc b/content/shell/webkit_test_controller.cc index d30444d..7af5ef8 100644 --- a/content/shell/webkit_test_controller.cc +++ b/content/shell/webkit_test_controller.cc @@ -22,6 +22,7 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_view.h" #include "content/shell/shell.h" #include "content/shell/shell_browser_context.h" #include "content/shell/shell_content_browser_client.h" @@ -223,6 +224,7 @@ bool WebKitTestController::PrepareForLayoutTest( WebContentsObserver::Observe(main_window_->web_contents()); send_configuration_to_next_host_ = true; current_pid_ = base::kNullProcessId; + main_window_->LoadURL(test_url); } else { #if (defined(OS_WIN) && !defined(USE_AURA)) || defined(TOOLKIT_GTK) // Shell::SizeTo is not implemented on all platforms. @@ -238,12 +240,14 @@ bool WebKitTestController::PrepareForLayoutTest( OverrideWebkitPrefs(&prefs); render_view_host->UpdateWebkitPreferences(prefs); SendTestConfiguration(); - registrar_.Add(this, - NOTIFICATION_NAV_ENTRY_PENDING, - Source<NavigationController>( - &main_window_->web_contents()->GetController())); + + NavigationController::LoadURLParams params(test_url); + params.transition_type = PageTransitionFromInt( + PAGE_TRANSITION_TYPED | PAGE_TRANSITION_FROM_ADDRESS_BAR); + params.should_clear_history_list = true; + main_window_->web_contents()->GetController().LoadURLWithParams(params); + main_window_->web_contents()->GetView()->Focus(); } - main_window_->LoadURL(test_url); main_window_->web_contents()->GetRenderViewHost()->SetActive(true); main_window_->web_contents()->GetRenderViewHost()->Focus(); if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoTimeout)) { @@ -396,11 +400,6 @@ void WebKitTestController::Observe(int type, current_pid_ = base::GetProcId(render_process_host->GetHandle()); break; } - case NOTIFICATION_NAV_ENTRY_PENDING: { - registrar_.Remove(this, NOTIFICATION_NAV_ENTRY_PENDING, source); - main_window_->web_contents()->GetController().PruneAllButActive(); - break; - } default: NOTREACHED(); } |