| Index: content/browser/frame_host/navigation_entry_impl.cc
|
| diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc
|
| index 694985aca8d0ad0a52054082f2eea5f4edd0f5db..44e479ec33c9550a3d11840cc65537753df94395 100644
|
| --- a/content/browser/frame_host/navigation_entry_impl.cc
|
| +++ b/content/browser/frame_host/navigation_entry_impl.cc
|
| @@ -17,6 +17,12 @@
|
| #include "content/public/common/url_constants.h"
|
| #include "ui/gfx/text_elider.h"
|
|
|
| +using base::UTF16ToUTF8;
|
| +
|
| +namespace content {
|
| +
|
| +namespace {
|
| +
|
| // Use this to get a new unique ID for a NavigationEntry during construction.
|
| // The returned ID is guaranteed to be nonzero (which is the "no ID" indicator).
|
| static int GetUniqueIDInConstructor() {
|
| @@ -24,7 +30,43 @@ static int GetUniqueIDInConstructor() {
|
| return ++unique_id_counter;
|
| }
|
|
|
| -namespace content {
|
| +void RecursivelyGenerateFrameEntries(const ExplodedFrameState& state,
|
| + NavigationEntryImpl::TreeNode* node) {
|
| + node->frame_entry = new FrameNavigationEntry(
|
| + -1, UTF16ToUTF8(state.target.string()), state.item_sequence_number,
|
| + state.document_sequence_number, nullptr, GURL(state.url_string.string()),
|
| + Referrer(GURL(state.referrer.string()), state.referrer_policy));
|
| +
|
| + node->frame_entry->set_frame_state(state);
|
| +
|
| + for (const ExplodedFrameState& child_state : state.children) {
|
| + NavigationEntryImpl::TreeNode* child_node =
|
| + new NavigationEntryImpl::TreeNode(nullptr);
|
| + node->children.push_back(child_node);
|
| + RecursivelyGenerateFrameEntries(child_state, child_node);
|
| + }
|
| +}
|
| +
|
| +void RecursivelyGenerateFrameState(
|
| + NavigationEntryImpl::TreeNode* node,
|
| + ExplodedFrameState* state,
|
| + std::vector<base::NullableString16>* referenced_files) {
|
| + // Copy the FrameNavigationEntry's frame state into the destination state.
|
| + *state = node->frame_entry->frame_state();
|
| +
|
| + // TODO(creis): Copy the referenced files from frame_entry into
|
| + // referenced_files (which is from PageState). Need to implement helper.
|
| + // ToNullableString16Vector(node->frame_entry->referenced_files(),
|
| + // referenced_files);
|
| +
|
| + state->children.resize(node->children.size());
|
| + for (size_t i = 0; i < node->children.size(); ++i) {
|
| + RecursivelyGenerateFrameState(node->children[i], &state->children[i],
|
| + referenced_files);
|
| + }
|
| +}
|
| +
|
| +} // namespace
|
|
|
| int NavigationEntryImpl::kInvalidBindings = -1;
|
|
|
| @@ -180,22 +222,45 @@ const base::string16& NavigationEntryImpl::GetTitle() const {
|
| }
|
|
|
| void NavigationEntryImpl::SetPageState(const PageState& state) {
|
| - frame_tree_->frame_entry->set_page_state(state);
|
| + page_state_ = state;
|
|
|
| - if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
|
| - // Also get the root ISN and DSN out of the PageState.
|
| - ExplodedPageState exploded_state;
|
| - if (!DecodePageState(state.ToEncodedData(), &exploded_state))
|
| - return;
|
| - frame_tree_->frame_entry->set_item_sequence_number(
|
| - exploded_state.top.item_sequence_number);
|
| - frame_tree_->frame_entry->set_document_sequence_number(
|
| - exploded_state.top.document_sequence_number);
|
| + if (!SiteIsolationPolicy::UseSubframeNavigationEntries())
|
| + return;
|
| +
|
| + // This should only be called when restoring a NavigationEntry, so there
|
| + // should be no subframe FrameNavigationEntries yet.
|
| + DCHECK_EQ(0U, frame_tree_->children.size());
|
| +
|
| + ExplodedPageState exploded_state;
|
| + if (!DecodePageState(state.ToEncodedData(), &exploded_state)) {
|
| + // Give up and set an empty ExplodedFrameState on the main frame.
|
| + frame_tree_->frame_entry->set_frame_state(ExplodedFrameState());
|
| + return;
|
| }
|
| +
|
| + RecursivelyGenerateFrameEntries(exploded_state.top, frame_tree_.get());
|
| }
|
|
|
| const PageState& NavigationEntryImpl::GetPageState() const {
|
| - return frame_tree_->frame_entry->page_state();
|
| + return page_state_;
|
| +}
|
| +
|
| +void NavigationEntryImpl::UpdatePageState() {
|
| + // When we're using subframe entries, each FrameNavigationEntry has a
|
| + // frame-specific PageState. We combine these into an ExplodedPageState tree
|
| + // and generate a full PageState from it.
|
| + DCHECK(SiteIsolationPolicy::UseSubframeNavigationEntries());
|
| + ExplodedPageState exploded_state;
|
| + RecursivelyGenerateFrameState(frame_tree_.get(), &exploded_state.top,
|
| + &exploded_state.referenced_files);
|
| +
|
| + std::string encoded_data;
|
| + if (!EncodePageState(exploded_state, &encoded_data)) {
|
| + page_state_ = PageState();
|
| + return;
|
| + }
|
| +
|
| + page_state_ = PageState::CreateFromEncodedData(encoded_data);
|
| }
|
|
|
| void NavigationEntryImpl::SetPageID(int page_id) {
|
| @@ -518,10 +583,17 @@ RequestNavigationParams NavigationEntryImpl::ConstructRequestNavigationParams(
|
| current_offset_to_send = -1;
|
| current_length_to_send = 0;
|
| }
|
| +
|
| + // Use the actual PageState in default Chrome, and only send the frame state
|
| + // in OOPIF modes.
|
| + PageState page_state = SiteIsolationPolicy::UseSubframeNavigationEntries()
|
| + ? PageState()
|
| + : GetPageState();
|
| +
|
| return RequestNavigationParams(
|
| GetIsOverridingUserAgent(), redirects, GetCanLoadLocalResources(),
|
| - base::Time::Now(), frame_entry.page_state(), GetPageID(), GetUniqueID(),
|
| - is_same_document_history_load, has_committed_real_load,
|
| + base::Time::Now(), page_state, frame_entry.frame_state(), GetPageID(),
|
| + GetUniqueID(), is_same_document_history_load, has_committed_real_load,
|
| intended_as_new_entry, pending_offset_to_send, current_offset_to_send,
|
| current_length_to_send, should_clear_history_list());
|
| }
|
| @@ -555,7 +627,7 @@ void NavigationEntryImpl::AddOrUpdateFrameEntry(
|
| SiteInstanceImpl* site_instance,
|
| const GURL& url,
|
| const Referrer& referrer,
|
| - const PageState& page_state) {
|
| + const ExplodedFrameState& frame_state) {
|
| // We should already have a TreeNode for the parent node by the time this node
|
| // commits. Find it first.
|
| DCHECK(frame_tree_node->parent());
|
| @@ -574,7 +646,7 @@ void NavigationEntryImpl::AddOrUpdateFrameEntry(
|
| // Update the existing FrameNavigationEntry (e.g., for replaceState).
|
| child->frame_entry->UpdateEntry(frame_unique_name, item_sequence_number,
|
| document_sequence_number, site_instance,
|
| - url, referrer, page_state);
|
| + url, referrer, frame_state);
|
| return;
|
| }
|
| }
|
| @@ -585,7 +657,7 @@ void NavigationEntryImpl::AddOrUpdateFrameEntry(
|
| FrameNavigationEntry* frame_entry = new FrameNavigationEntry(
|
| frame_tree_node_id, frame_unique_name, item_sequence_number,
|
| document_sequence_number, site_instance, url, referrer);
|
| - frame_entry->set_page_state(page_state);
|
| + frame_entry->set_frame_state(frame_state);
|
| parent_node->children.push_back(
|
| new NavigationEntryImpl::TreeNode(frame_entry));
|
| }
|
|
|