| 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 8d889c9e189627d91ea2acd7cd5578ac7dcafc9e..288bfa8dca858498955daeea529fd94b4dd3fed7 100644
|
| --- a/content/browser/frame_host/navigation_entry_impl.cc
|
| +++ b/content/browser/frame_host/navigation_entry_impl.cc
|
| @@ -44,13 +44,28 @@ bool NavigationEntryImpl::TreeNode::MatchesFrame(
|
| frame_entry->frame_tree_node_id() == -1;
|
| }
|
|
|
| -NavigationEntryImpl::TreeNode* NavigationEntryImpl::TreeNode::Clone() const {
|
| +scoped_ptr<NavigationEntryImpl::TreeNode>
|
| +NavigationEntryImpl::TreeNode::CloneAndReplace(
|
| + FrameTreeNode* frame_tree_node,
|
| + FrameNavigationEntry* frame_navigation_entry) const {
|
| + if (frame_tree_node && MatchesFrame(frame_tree_node)) {
|
| + // Replace this node in the cloned tree and prune its children.
|
| + return make_scoped_ptr(
|
| + new NavigationEntryImpl::TreeNode(frame_navigation_entry));
|
| + }
|
| +
|
| // Clone the tree using a copy of the FrameNavigationEntry, without sharing.
|
| - NavigationEntryImpl::TreeNode* copy =
|
| - new NavigationEntryImpl::TreeNode(frame_entry->Clone());
|
| + // TODO(creis): Share FNEs unless it's for another tab.
|
| + scoped_ptr<NavigationEntryImpl::TreeNode> copy(
|
| + new NavigationEntryImpl::TreeNode(frame_entry->Clone()));
|
| +
|
| + // Recursively clone the children.
|
| + for (auto& child : children) {
|
| + copy->children.push_back(
|
| + child->CloneAndReplace(frame_tree_node, frame_navigation_entry));
|
| + }
|
|
|
| - // TODO(creis): Clone children once we add them.
|
| - return copy;
|
| + return copy.Pass();
|
| }
|
|
|
| NavigationEntry* NavigationEntry::Create() {
|
| @@ -351,11 +366,18 @@ void NavigationEntryImpl::ClearExtraData(const std::string& key) {
|
| }
|
|
|
| NavigationEntryImpl* NavigationEntryImpl::Clone() const {
|
| + return NavigationEntryImpl::CloneAndReplace(nullptr, nullptr);
|
| +}
|
| +
|
| +NavigationEntryImpl* NavigationEntryImpl::CloneAndReplace(
|
| + FrameTreeNode* frame_tree_node,
|
| + FrameNavigationEntry* frame_navigation_entry) const {
|
| NavigationEntryImpl* copy = new NavigationEntryImpl();
|
|
|
| // TODO(creis): Only share the same FrameNavigationEntries if cloning within
|
| // the same tab.
|
| - copy->frame_tree_.reset(frame_tree_->Clone());
|
| + copy->frame_tree_ =
|
| + frame_tree_->CloneAndReplace(frame_tree_node, frame_navigation_entry);
|
|
|
| // Copy most state over, unless cleared in ResetForCommit.
|
| // Don't copy unique_id_, otherwise it won't be unique.
|
| @@ -493,9 +515,8 @@ void NavigationEntryImpl::AddOrUpdateFrameEntry(FrameTreeNode* frame_tree_node,
|
| FindFrameEntry(frame_tree_node->parent());
|
| if (!parent_node) {
|
| // The renderer should not send a commit for a subframe before its parent.
|
| - // TODO(creis): This can currently happen because we don't yet clone the
|
| - // FrameNavigationEntry tree on manual subframe navigations. Once that's
|
| - // added, we should kill the renderer if we get here.
|
| + // TODO(creis): Kill the renderer if we get here.
|
| + NOTREACHED() << "Shouldn't see a commit for a subframe before parent.";
|
| return;
|
| }
|
|
|
| @@ -503,7 +524,7 @@ void NavigationEntryImpl::AddOrUpdateFrameEntry(FrameTreeNode* frame_tree_node,
|
| int frame_tree_node_id = frame_tree_node->frame_tree_node_id();
|
| for (TreeNode* child : parent_node->children) {
|
| if (child->frame_entry->frame_tree_node_id() == frame_tree_node_id) {
|
| - // Update the existing FrameNavigationEntry.
|
| + // Update the existing FrameNavigationEntry (e.g., for replaceState).
|
| child->frame_entry->UpdateEntry(site_instance, url, referrer, page_state);
|
| return;
|
| }
|
|
|