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

Unified Diff: content/renderer/render_frame_impl.cc

Issue 2550113002: Send a subtree of same-process PageStates for back/forward child frames.
Patch Set: Rebase Created 4 years 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 5007f28f5c19f40d05bae2cdb26a00a3940ca5de..6579a3e86b128597283d52d154f0eddb413ee837 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -3244,10 +3244,31 @@ void RenderFrameImpl::loadURLExternally(const blink::WebURLRequest& request,
}
blink::WebHistoryItem RenderFrameImpl::historyItemForNewChildFrame() {
- // OOPIF enabled modes will punt this navigation to the browser in
- // decidePolicyForNavigation.
- if (SiteIsolationPolicy::UseSubframeNavigationEntries())
+ if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+ // Check whether the browser process provided a history item to use for this
+ // new frame. If not, return an empty WebHistoryItem and check with the
+ // browser process in decidePolicyForNavigation.
+ const std::string& unique_name = frame_->uniqueName().utf8();
+ const auto& iter = render_view_->history_page_states_.find(unique_name);
+ if (iter != render_view_->history_page_states_.end()) {
+ const PageState& page_state = iter->second;
+ // If the PageState is non-empty, use it as the history item to load. If
+ // it is empty, it represents a cross-process history item. We'll ask the
+ // browser process to handle it in decidePolicyForNavigation.
+ if (page_state.IsValid()) {
+ std::unique_ptr<HistoryEntry> entry =
+ PageStateToHistoryEntry(page_state);
+
+ // Erase the entry now that we've used it (unlike the empty PageState
+ // case).
+ render_view_->history_page_states_.erase(unique_name);
+
+ return entry->root();
+ }
+ }
+
return WebHistoryItem();
+ }
return render_view_->history_controller()->GetItemForNewChildFrame(this);
}
@@ -4983,11 +5004,6 @@ void RenderFrameImpl::didStopLoading() {
TRACE_EVENT1("navigation,rail", "RenderFrameImpl::didStopLoading",
"id", routing_id_);
- // Any subframes created after this point won't be considered part of the
- // current history navigation (if this was one), so we don't need to track
- // this state anymore.
- history_subframe_unique_names_.clear();
-
render_view_->FrameDidStopLoading(frame_);
Send(new FrameHostMsg_DidStopLoading(routing_id_));
}
@@ -5154,27 +5170,34 @@ WebNavigationPolicy RenderFrameImpl::decidePolicyForNavigation(
return blink::WebNavigationPolicyIgnore; // Suppress the load here.
}
- // In OOPIF-enabled modes, back/forward navigations in newly created subframes
- // should be sent to the browser if there is a matching FrameNavigationEntry,
- // and if it isn't just staying at about:blank. If this frame isn't in the
- // map of unique names that have history items, or if it's staying at the
- // initial about:blank URL, fall back to loading the default url. (We remove
- // each name as we encounter it, because it will only be used once as the
- // frame is created.)
+ // Back/forward navigations in newly created subframes should be sent to the
+ // browser process if there is a matching unique name in the PageState map but
+ // the PageState is empty. This is a signal that the browser process has a
+ // FrameNavigationEntry for it but that it will load in a different process.
+ // We remove each name as we encounter it, because it will only be used once
+ // as the frame is created.
+ //
+ // If this frame isn't in the map (or has already been removed during
+ // historyItemForNewChildFrame), allow the navigation to continue. For frames
+ // that were never in the map, this effectively falls back to loading the
+ // default URL for the frame.
if (SiteIsolationPolicy::UseSubframeNavigationEntries() &&
info.isHistoryNavigationInNewChildFrame && is_content_initiated &&
frame_->parent()) {
- // Check whether the browser has a history item for this frame that isn't
- // just staying at the initial about:blank document.
+ // Check whether the browser process sent an empty PageState for this frame,
+ // indicating that it should load in a different process.
bool should_ask_browser = false;
- RenderFrameImpl* parent = RenderFrameImpl::FromWebFrame(frame_->parent());
- const auto& iter = parent->history_subframe_unique_names_.find(
- frame_->uniqueName().utf8());
- if (iter != parent->history_subframe_unique_names_.end()) {
- bool history_item_is_about_blank = iter->second;
- should_ask_browser =
- !history_item_is_about_blank || url != url::kAboutBlankURL;
- parent->history_subframe_unique_names_.erase(frame_->uniqueName().utf8());
+ const std::string& unique_name = frame_->uniqueName().utf8();
+ const auto& iter = render_view_->history_page_states_.find(unique_name);
+ if (iter != render_view_->history_page_states_.end()) {
+ const PageState& page_state = iter->second;
+
+ // If the PageState were valid, we should have used and removed it in
+ // historyItemForNewChildFrame.
+ DCHECK(!page_state.IsValid());
+
+ should_ask_browser = !page_state.IsValid();
+ render_view_->history_page_states_.erase(unique_name);
}
if (should_ask_browser) {
@@ -5827,8 +5850,10 @@ void RenderFrameImpl::NavigateInternal(
should_load_request = true;
// Keep track of which subframes the browser process has history items
- // for during a history navigation.
- history_subframe_unique_names_ = request_params.subframe_unique_names;
+ // for during a history navigation (in addition to any existing ones,
+ // overwriting any stale entries).
+ for (const auto& iter : request_params.subtree_page_states)
+ render_view_->history_page_states_[iter.first] = iter.second;
if (history_load_type == blink::WebHistorySameDocumentLoad) {
// If this is marked as a same document load but we haven't committed
« 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