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

Unified Diff: content/renderer/render_frame_impl.cc

Issue 1027863002: Move provisional navigation parameters to RenderFrame, and use the HistoryController to distribute … (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixes Created 5 years, 9 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
« no previous file with comments | « content/renderer/render_frame_impl.h ('k') | content/renderer/render_view_impl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/render_frame_impl.cc
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index be10cdabedb523475f8ceb2fa2712d21fb2cadc2..d640f9d85f645aae77caebde3c74e2ac5f92422e 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -38,6 +38,7 @@
#include "content/common/frame_messages.h"
#include "content/common/frame_replication_state.h"
#include "content/common/input_messages.h"
+#include "content/common/navigation_params.h"
#include "content/common/service_worker/service_worker_types.h"
#include "content/common/swapped_out_messages.h"
#include "content/common/view_messages.h"
@@ -488,6 +489,12 @@ media::Context3D GetSharedMainThreadContext3D() {
}
#endif
+bool IsReload(FrameMsg_Navigate_Type::Value navigation_type) {
+ return navigation_type == FrameMsg_Navigate_Type::RELOAD ||
+ navigation_type == FrameMsg_Navigate_Type::RELOAD_IGNORING_CACHE ||
+ navigation_type == FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL;
+}
+
RenderFrameImpl::CreateRenderFrameImplFunction g_create_render_frame_impl =
nullptr;
@@ -1046,7 +1053,7 @@ void RenderFrameImpl::OnNavigate(
TRACE_EVENT2("navigation", "RenderFrameImpl::OnNavigate", "id", routing_id_,
"url", common_params.url.possibly_invalid_spec());
- bool is_reload = RenderViewImpl::IsReload(common_params.navigation_type);
+ bool is_reload = IsReload(common_params.navigation_type);
bool is_history_navigation = request_params.page_state.IsValid();
WebURLRequest::CachePolicy cache_policy =
WebURLRequest::UseProtocolCachePolicy;
@@ -1075,7 +1082,7 @@ void RenderFrameImpl::OnNavigate(
cache_policy = WebURLRequest::ReloadIgnoringCacheData;
}
- render_view_->pending_navigation_params_.reset(
+ pending_navigation_params_.reset(
new NavigationParams(common_params, start_params, request_params));
// If we are reloading, then WebKit will use the history state of the current
@@ -1102,7 +1109,10 @@ void RenderFrameImpl::OnNavigate(
// Ensure we didn't save the swapped out URL in UpdateState, since the
// browser should never be telling us to navigate to swappedout://.
CHECK(entry->root().urlString() != WebString::fromUTF8(kSwappedOutURL));
- render_view_->history_controller()->GoToEntry(entry.Pass(), cache_policy);
+ scoped_ptr<NavigationParams> navigation_params(
+ new NavigationParams(*pending_navigation_params_.get()));
+ render_view_->history_controller()->GoToEntry(
+ entry.Pass(), navigation_params.Pass(), cache_policy);
}
} else if (!common_params.base_url_for_data_url.is_empty()) {
LoadDataURL(common_params, frame);
@@ -1150,8 +1160,8 @@ void RenderFrameImpl::OnNavigate(
renderer_navigation_start);
}
- // In case LoadRequest failed before DidCreateDataSource was called.
- render_view_->pending_navigation_params_.reset();
+ // In case LoadRequest failed before didCreateDataSource was called.
+ pending_navigation_params_.reset();
}
void RenderFrameImpl::NavigateToSwappedOutURL() {
@@ -1178,6 +1188,11 @@ ManifestManager* RenderFrameImpl::manifest_manager() {
return manifest_manager_;
}
+void RenderFrameImpl::SetPendingNavigationParams(
+ scoped_ptr<NavigationParams> navigation_params) {
+ pending_navigation_params_ = navigation_params.Pass();
+}
+
void RenderFrameImpl::OnBeforeUnload() {
TRACE_EVENT1("navigation", "RenderFrameImpl::OnBeforeUnload",
"id", routing_id_);
@@ -2289,13 +2304,98 @@ void RenderFrameImpl::didCreateDataSource(blink::WebLocalFrame* frame,
blink::WebDataSource* datasource) {
DCHECK(!frame_ || frame_ == frame);
- // TODO(nasko): Move implementation here. Needed state:
- // * pending_navigation_params_
- // * webview
- // Needed methods:
- // * PopulateDocumentStateFromPending
- // * CreateNavigationStateFromPending
- render_view_->didCreateDataSource(frame, datasource);
+ bool content_initiated = !pending_navigation_params_.get();
+
+ // Make sure any previous redirect URLs end up in our new data source.
+ if (pending_navigation_params_.get()) {
+ for (const auto& i :
+ pending_navigation_params_->request_params.redirects) {
+ datasource->appendRedirect(i);
+ }
+ }
+
+ DocumentState* document_state = DocumentState::FromDataSource(datasource);
+ if (!document_state) {
+ document_state = new DocumentState;
+ datasource->setExtraData(document_state);
+ if (!content_initiated)
+ PopulateDocumentStateFromPending(document_state);
+ }
+
+ // Carry over the user agent override flag, if it exists.
+ blink::WebView* webview = render_view_->webview();
+ if (content_initiated && webview && webview->mainFrame() &&
+ webview->mainFrame()->isWebLocalFrame() &&
+ webview->mainFrame()->dataSource()) {
+ DocumentState* old_document_state =
+ DocumentState::FromDataSource(webview->mainFrame()->dataSource());
+ if (old_document_state) {
+ InternalDocumentStateData* internal_data =
+ InternalDocumentStateData::FromDocumentState(document_state);
+ InternalDocumentStateData* old_internal_data =
+ InternalDocumentStateData::FromDocumentState(old_document_state);
+ internal_data->set_is_overriding_user_agent(
+ old_internal_data->is_overriding_user_agent());
+ }
+ }
+
+ // The rest of RenderView assumes that a WebDataSource will always have a
+ // non-null NavigationState.
+ if (content_initiated) {
+ document_state->set_navigation_state(
+ NavigationStateImpl::CreateContentInitiated());
+ } else {
+ document_state->set_navigation_state(CreateNavigationStateFromPending());
+ pending_navigation_params_.reset();
+ }
+
+ // DocumentState::referred_by_prefetcher_ is true if we are
+ // navigating from a page that used prefetching using a link on that
+ // page. We are early enough in the request process here that we
+ // can still see the DocumentState of the previous page and set
+ // this value appropriately.
+ // TODO(gavinp): catch the important case of navigation in a new
+ // renderer process.
+ if (webview) {
+ if (WebFrame* old_frame = webview->mainFrame()) {
+ const WebURLRequest& original_request = datasource->originalRequest();
+ const GURL referrer(
+ original_request.httpHeaderField(WebString::fromUTF8("Referer")));
+ if (!referrer.is_empty() && old_frame->isWebLocalFrame() &&
+ DocumentState::FromDataSource(old_frame->dataSource())
+ ->was_prefetcher()) {
+ for (; old_frame; old_frame = old_frame->traverseNext(false)) {
+ WebDataSource* old_frame_datasource = old_frame->dataSource();
+ if (old_frame_datasource &&
+ referrer == GURL(old_frame_datasource->request().url())) {
+ document_state->set_was_referred_by_prefetcher(true);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (content_initiated) {
+ const WebURLRequest& request = datasource->request();
+ switch (request.cachePolicy()) {
+ case WebURLRequest::UseProtocolCachePolicy: // normal load.
+ document_state->set_load_type(DocumentState::LINK_LOAD_NORMAL);
+ break;
+ case WebURLRequest::ReloadIgnoringCacheData: // reload.
+ case WebURLRequest::ReloadBypassingCache: // end-to-end reload.
+ document_state->set_load_type(DocumentState::LINK_LOAD_RELOAD);
+ break;
+ case WebURLRequest::ReturnCacheDataElseLoad: // allow stale data.
+ document_state->set_load_type(DocumentState::LINK_LOAD_CACHE_STALE_OK);
+ break;
+ case WebURLRequest::ReturnCacheDataDontLoad: // Don't re-post.
+ document_state->set_load_type(DocumentState::LINK_LOAD_CACHE_ONLY);
+ break;
+ default:
+ NOTREACHED();
+ }
+ }
// Create the serviceworker's per-document network observing object if it
// does not exist (When navigation happens within a page, the provider already
@@ -2453,10 +2553,10 @@ void RenderFrameImpl::didFailProvisionalLoad(blink::WebLocalFrame* frame,
// If we failed on a browser initiated request, then make sure that our error
// page load is regarded as the same browser initiated request.
if (!navigation_state->IsContentInitiated()) {
- render_view_->pending_navigation_params_.reset(new NavigationParams(
+ pending_navigation_params_.reset(new NavigationParams(
navigation_state->common_params(), navigation_state->start_params(),
navigation_state->request_params()));
- render_view_->pending_navigation_params_->request_params.request_time =
+ pending_navigation_params_->request_params.request_time =
document_state->request_time();
}
@@ -2541,8 +2641,7 @@ void RenderFrameImpl::didCommitProvisionalLoad(
// reload, the page ID doesn't change, and UpdateSessionHistory gets the
// previous URL and the current page ID, which would be wrong.
if (navigation_state->request_params().page_id != -1 &&
- navigation_state->request_params().page_id != render_view_->page_id_ &&
- !navigation_state->request_committed()) {
+ navigation_state->request_params().page_id != render_view_->page_id_) {
// This is a successful session history navigation!
render_view_->page_id_ = navigation_state->request_params().page_id;
@@ -2769,7 +2868,7 @@ void RenderFrameImpl::didNavigateWithinPage(blink::WebLocalFrame* frame,
// ExtraData will get the new NavigationState. Similarly, if we did not
// initiate this navigation, then we need to take care to reset any pre-
// existing navigation state to a content-initiated navigation state.
- // DidCreateDataSource conveniently takes care of this for us.
+ // didCreateDataSource conveniently takes care of this for us.
didCreateDataSource(frame, frame->dataSource());
DocumentState* document_state =
@@ -3924,7 +4023,7 @@ void RenderFrameImpl::OnCommitNavigation(
GetContentClient()->SetActiveURL(common_params.url);
- render_view_->pending_navigation_params_.reset(new NavigationParams(
+ pending_navigation_params_.reset(new NavigationParams(
common_params, StartNavigationParams(), request_params));
if (!common_params.base_url_for_data_url.is_empty() ||
@@ -4465,6 +4564,61 @@ GURL RenderFrameImpl::GetLoadingUrl() const {
return request.url();
}
+void RenderFrameImpl::PopulateDocumentStateFromPending(
+ DocumentState* document_state) {
+ document_state->set_request_time(
+ pending_navigation_params_->request_params.request_time);
+
+ InternalDocumentStateData* internal_data =
+ InternalDocumentStateData::FromDocumentState(document_state);
+
+ if (!pending_navigation_params_->common_params.url.SchemeIs(
+ url::kJavaScriptScheme) &&
+ pending_navigation_params_->common_params.navigation_type ==
+ FrameMsg_Navigate_Type::RESTORE) {
+ // We're doing a load of a page that was restored from the last session. By
+ // default this prefers the cache over loading (LOAD_PREFERRING_CACHE) which
+ // can result in stale data for pages that are set to expire. We explicitly
+ // override that by setting the policy here so that as necessary we load
+ // from the network.
+ //
+ // TODO(davidben): Remove this in favor of passing a cache policy to the
+ // loadHistoryItem call in OnNavigate. That requires not overloading
+ // UseProtocolCachePolicy to mean both "normal load" and "determine cache
+ // policy based on load type, etc".
+ internal_data->set_cache_policy_override(
+ WebURLRequest::UseProtocolCachePolicy);
+ }
+
+ if (IsReload(pending_navigation_params_->common_params.navigation_type))
+ document_state->set_load_type(DocumentState::RELOAD);
+ else if (pending_navigation_params_->request_params.page_state.IsValid())
+ document_state->set_load_type(DocumentState::HISTORY_LOAD);
+ else
+ document_state->set_load_type(DocumentState::NORMAL_LOAD);
+
+ internal_data->set_is_overriding_user_agent(
+ pending_navigation_params_->request_params.is_overriding_user_agent);
+ internal_data->set_must_reset_scroll_and_scale_state(
+ pending_navigation_params_->common_params.navigation_type ==
+ FrameMsg_Navigate_Type::RELOAD_ORIGINAL_REQUEST_URL);
+ document_state->set_can_load_local_resources(
+ pending_navigation_params_->request_params.can_load_local_resources);
+}
+
+NavigationState* RenderFrameImpl::CreateNavigationStateFromPending() {
+ // A navigation resulting from loading a javascript URL should not be treated
+ // as a browser initiated event. Instead, we want it to look as if the page
+ // initiated any load resulting from JS execution.
+ if (!pending_navigation_params_->common_params.url.SchemeIs(
+ url::kJavaScriptScheme)) {
+ return NavigationStateImpl::CreateBrowserInitiated(
+ pending_navigation_params_->common_params,
+ pending_navigation_params_->start_params,
+ pending_navigation_params_->request_params);
+ }
+ return NavigationStateImpl::CreateContentInitiated();
+}
#if defined(OS_ANDROID)
WebMediaPlayer* RenderFrameImpl::CreateAndroidWebMediaPlayer(
« no previous file with comments | « content/renderer/render_frame_impl.h ('k') | content/renderer/render_view_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698