| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/frame_host/navigation_entry_impl.h" | 5 #include "content/browser/frame_host/navigation_entry_impl.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <queue> | 9 #include <queue> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 EncodePageState(page_state, &data); | 67 EncodePageState(page_state, &data); |
| 68 DCHECK(!data.empty()) << "Shouldn't generate an empty PageState."; | 68 DCHECK(!data.empty()) << "Shouldn't generate an empty PageState."; |
| 69 node->frame_entry->SetPageState(PageState::CreateFromEncodedData(data)); | 69 node->frame_entry->SetPageState(PageState::CreateFromEncodedData(data)); |
| 70 | 70 |
| 71 // Don't pass the file list to subframes, since that would result in multiple | 71 // Don't pass the file list to subframes, since that would result in multiple |
| 72 // copies of it ending up in the combined list in GetPageState (via | 72 // copies of it ending up in the combined list in GetPageState (via |
| 73 // RecursivelyGenerateFrameState). | 73 // RecursivelyGenerateFrameState). |
| 74 std::vector<base::NullableString16> empty_file_list; | 74 std::vector<base::NullableString16> empty_file_list; |
| 75 | 75 |
| 76 for (const ExplodedFrameState& child_state : state.children) { | 76 for (const ExplodedFrameState& child_state : state.children) { |
| 77 NavigationEntryImpl::TreeNode* child_node = | 77 node->children.push_back( |
| 78 new NavigationEntryImpl::TreeNode(node, nullptr); | 78 base::MakeUnique<NavigationEntryImpl::TreeNode>(node, nullptr)); |
| 79 node->children.push_back(child_node); | 79 RecursivelyGenerateFrameEntries(child_state, empty_file_list, |
| 80 RecursivelyGenerateFrameEntries(child_state, empty_file_list, child_node); | 80 node->children.back().get()); |
| 81 } | 81 } |
| 82 } | 82 } |
| 83 | 83 |
| 84 void RecursivelyGenerateFrameState( | 84 void RecursivelyGenerateFrameState( |
| 85 NavigationEntryImpl::TreeNode* node, | 85 NavigationEntryImpl::TreeNode* node, |
| 86 ExplodedFrameState* state, | 86 ExplodedFrameState* state, |
| 87 std::vector<base::NullableString16>* referenced_files) { | 87 std::vector<base::NullableString16>* referenced_files) { |
| 88 // The FrameNavigationEntry's PageState contains just the ExplodedFrameState | 88 // The FrameNavigationEntry's PageState contains just the ExplodedFrameState |
| 89 // for that particular frame. | 89 // for that particular frame. |
| 90 ExplodedPageState exploded_page_state; | 90 ExplodedPageState exploded_page_state; |
| 91 if (!DecodePageState(node->frame_entry->page_state().ToEncodedData(), | 91 if (!DecodePageState(node->frame_entry->page_state().ToEncodedData(), |
| 92 &exploded_page_state)) { | 92 &exploded_page_state)) { |
| 93 NOTREACHED(); | 93 NOTREACHED(); |
| 94 return; | 94 return; |
| 95 } | 95 } |
| 96 ExplodedFrameState frame_state = exploded_page_state.top; | 96 ExplodedFrameState frame_state = exploded_page_state.top; |
| 97 | 97 |
| 98 // Copy the FrameNavigationEntry's frame state into the destination state. | 98 // Copy the FrameNavigationEntry's frame state into the destination state. |
| 99 *state = frame_state; | 99 *state = frame_state; |
| 100 | 100 |
| 101 // Copy the frame's files into the PageState's |referenced_files|. | 101 // Copy the frame's files into the PageState's |referenced_files|. |
| 102 referenced_files->reserve(referenced_files->size() + | 102 referenced_files->reserve(referenced_files->size() + |
| 103 exploded_page_state.referenced_files.size()); | 103 exploded_page_state.referenced_files.size()); |
| 104 for (auto& file : exploded_page_state.referenced_files) | 104 for (auto& file : exploded_page_state.referenced_files) |
| 105 referenced_files->push_back(file); | 105 referenced_files->push_back(file); |
| 106 | 106 |
| 107 state->children.resize(node->children.size()); | 107 state->children.resize(node->children.size()); |
| 108 for (size_t i = 0; i < node->children.size(); ++i) { | 108 for (size_t i = 0; i < node->children.size(); ++i) { |
| 109 RecursivelyGenerateFrameState(node->children[i], &state->children[i], | 109 RecursivelyGenerateFrameState(node->children[i].get(), &state->children[i], |
| 110 referenced_files); | 110 referenced_files); |
| 111 } | 111 } |
| 112 } | 112 } |
| 113 | 113 |
| 114 // Walk the ancestor chain for both the |frame_tree_node| and the |node|. | 114 // Walk the ancestor chain for both the |frame_tree_node| and the |node|. |
| 115 // Comparing the inputs directly is not performed, as this method assumes they | 115 // Comparing the inputs directly is not performed, as this method assumes they |
| 116 // already match each other. Returns false if a mismatch in unique name or | 116 // already match each other. Returns false if a mismatch in unique name or |
| 117 // ancestor chain is detected, otherwise true. | 117 // ancestor chain is detected, otherwise true. |
| 118 bool InSameTreePosition(FrameTreeNode* frame_tree_node, | 118 bool InSameTreePosition(FrameTreeNode* frame_tree_node, |
| 119 NavigationEntryImpl::TreeNode* node) { | 119 NavigationEntryImpl::TreeNode* node) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 bool is_target_frame = | 167 bool is_target_frame = |
| 168 target_frame_tree_node && MatchesFrame(target_frame_tree_node); | 168 target_frame_tree_node && MatchesFrame(target_frame_tree_node); |
| 169 std::unique_ptr<NavigationEntryImpl::TreeNode> copy( | 169 std::unique_ptr<NavigationEntryImpl::TreeNode> copy( |
| 170 new NavigationEntryImpl::TreeNode( | 170 new NavigationEntryImpl::TreeNode( |
| 171 parent_node, | 171 parent_node, |
| 172 is_target_frame ? frame_navigation_entry : frame_entry->Clone())); | 172 is_target_frame ? frame_navigation_entry : frame_entry->Clone())); |
| 173 | 173 |
| 174 // Recursively clone the children if needed. | 174 // Recursively clone the children if needed. |
| 175 if (!is_target_frame || clone_children_of_target) { | 175 if (!is_target_frame || clone_children_of_target) { |
| 176 for (size_t i = 0; i < children.size(); i++) { | 176 for (size_t i = 0; i < children.size(); i++) { |
| 177 NavigationEntryImpl::TreeNode* child = children[i]; | 177 const auto& child = children[i]; |
| 178 | 178 |
| 179 // Don't check whether it's still in the tree if |current_frame_tree_node| | 179 // Don't check whether it's still in the tree if |current_frame_tree_node| |
| 180 // is null. | 180 // is null. |
| 181 if (!current_frame_tree_node) { | 181 if (!current_frame_tree_node) { |
| 182 copy->children.push_back(child->CloneAndReplace( | 182 copy->children.push_back(child->CloneAndReplace( |
| 183 frame_navigation_entry, clone_children_of_target, | 183 frame_navigation_entry, clone_children_of_target, |
| 184 target_frame_tree_node, nullptr, copy.get())); | 184 target_frame_tree_node, nullptr, copy.get())); |
| 185 continue; | 185 continue; |
| 186 } | 186 } |
| 187 | 187 |
| (...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 812 NavigationEntryImpl::TreeNode* parent_node = | 812 NavigationEntryImpl::TreeNode* parent_node = |
| 813 FindFrameEntry(frame_tree_node->parent()); | 813 FindFrameEntry(frame_tree_node->parent()); |
| 814 if (!parent_node) { | 814 if (!parent_node) { |
| 815 // The renderer should not send a commit for a subframe before its parent. | 815 // The renderer should not send a commit for a subframe before its parent. |
| 816 // TODO(creis): Kill the renderer if we get here. | 816 // TODO(creis): Kill the renderer if we get here. |
| 817 return; | 817 return; |
| 818 } | 818 } |
| 819 | 819 |
| 820 // Now check whether we have a TreeNode for the node itself. | 820 // Now check whether we have a TreeNode for the node itself. |
| 821 const std::string& unique_name = frame_tree_node->unique_name(); | 821 const std::string& unique_name = frame_tree_node->unique_name(); |
| 822 for (TreeNode* child : parent_node->children) { | 822 for (const auto& child : parent_node->children) { |
| 823 if (child->frame_entry->frame_unique_name() == unique_name) { | 823 if (child->frame_entry->frame_unique_name() == unique_name) { |
| 824 // If the document of the FrameNavigationEntry is changing, we must clear | 824 // If the document of the FrameNavigationEntry is changing, we must clear |
| 825 // any child FrameNavigationEntries. | 825 // any child FrameNavigationEntries. |
| 826 if (child->frame_entry->document_sequence_number() != | 826 if (child->frame_entry->document_sequence_number() != |
| 827 document_sequence_number) | 827 document_sequence_number) |
| 828 child->children.clear(); | 828 child->children.clear(); |
| 829 | 829 |
| 830 // Update the existing FrameNavigationEntry (e.g., for replaceState). | 830 // Update the existing FrameNavigationEntry (e.g., for replaceState). |
| 831 child->frame_entry->UpdateEntry( | 831 child->frame_entry->UpdateEntry( |
| 832 unique_name, item_sequence_number, document_sequence_number, | 832 unique_name, item_sequence_number, document_sequence_number, |
| 833 site_instance, std::move(source_site_instance), url, referrer, | 833 site_instance, std::move(source_site_instance), url, referrer, |
| 834 redirect_chain, page_state, method, post_id); | 834 redirect_chain, page_state, method, post_id); |
| 835 return; | 835 return; |
| 836 } | 836 } |
| 837 } | 837 } |
| 838 | 838 |
| 839 // No entry exists yet, so create a new one. | 839 // No entry exists yet, so create a new one. |
| 840 // Unordered list, since we expect to look up entries by frame sequence number | 840 // Unordered list, since we expect to look up entries by frame sequence number |
| 841 // or unique name. | 841 // or unique name. |
| 842 FrameNavigationEntry* frame_entry = new FrameNavigationEntry( | 842 FrameNavigationEntry* frame_entry = new FrameNavigationEntry( |
| 843 unique_name, item_sequence_number, document_sequence_number, | 843 unique_name, item_sequence_number, document_sequence_number, |
| 844 site_instance, std::move(source_site_instance), url, referrer, method, | 844 site_instance, std::move(source_site_instance), url, referrer, method, |
| 845 post_id); | 845 post_id); |
| 846 frame_entry->SetPageState(page_state); | 846 frame_entry->SetPageState(page_state); |
| 847 frame_entry->set_redirect_chain(redirect_chain); | 847 frame_entry->set_redirect_chain(redirect_chain); |
| 848 parent_node->children.push_back( | 848 parent_node->children.push_back( |
| 849 new NavigationEntryImpl::TreeNode(parent_node, frame_entry)); | 849 base::MakeUnique<NavigationEntryImpl::TreeNode>(parent_node, |
| 850 frame_entry)); |
| 850 } | 851 } |
| 851 | 852 |
| 852 FrameNavigationEntry* NavigationEntryImpl::GetFrameEntry( | 853 FrameNavigationEntry* NavigationEntryImpl::GetFrameEntry( |
| 853 FrameTreeNode* frame_tree_node) const { | 854 FrameTreeNode* frame_tree_node) const { |
| 854 NavigationEntryImpl::TreeNode* tree_node = FindFrameEntry(frame_tree_node); | 855 NavigationEntryImpl::TreeNode* tree_node = FindFrameEntry(frame_tree_node); |
| 855 return tree_node ? tree_node->frame_entry.get() : nullptr; | 856 return tree_node ? tree_node->frame_entry.get() : nullptr; |
| 856 } | 857 } |
| 857 | 858 |
| 858 std::map<std::string, bool> NavigationEntryImpl::GetSubframeUniqueNames( | 859 std::map<std::string, bool> NavigationEntryImpl::GetSubframeUniqueNames( |
| 859 FrameTreeNode* frame_tree_node) const { | 860 FrameTreeNode* frame_tree_node) const { |
| 860 std::map<std::string, bool> names; | 861 std::map<std::string, bool> names; |
| 861 NavigationEntryImpl::TreeNode* tree_node = FindFrameEntry(frame_tree_node); | 862 NavigationEntryImpl::TreeNode* tree_node = FindFrameEntry(frame_tree_node); |
| 862 if (tree_node) { | 863 if (tree_node) { |
| 863 // Return the names of all immediate children. | 864 // Return the names of all immediate children. |
| 864 for (TreeNode* child : tree_node->children) { | 865 for (const auto& child : tree_node->children) { |
| 865 // Keep track of whether we would be loading about:blank, since the | 866 // Keep track of whether we would be loading about:blank, since the |
| 866 // renderer should be allowed to just commit the initial blank frame if | 867 // renderer should be allowed to just commit the initial blank frame if |
| 867 // that was the default URL. PageState doesn't matter there, because | 868 // that was the default URL. PageState doesn't matter there, because |
| 868 // content injected into about:blank frames doesn't use it. | 869 // content injected into about:blank frames doesn't use it. |
| 869 // | 870 // |
| 870 // Be careful not to rely on FrameNavigationEntry's URLs in this check, | 871 // Be careful not to rely on FrameNavigationEntry's URLs in this check, |
| 871 // because the committed URL in the browser could be rewritten to | 872 // because the committed URL in the browser could be rewritten to |
| 872 // about:blank. | 873 // about:blank. |
| 873 // See RenderProcessHostImpl::FilterURL to know which URLs are rewritten. | 874 // See RenderProcessHostImpl::FilterURL to know which URLs are rewritten. |
| 874 // See https://crbug.com/657896 for details. | 875 // See https://crbug.com/657896 for details. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 895 std::queue<NavigationEntryImpl::TreeNode*> work_queue; | 896 std::queue<NavigationEntryImpl::TreeNode*> work_queue; |
| 896 int count = 0; | 897 int count = 0; |
| 897 | 898 |
| 898 work_queue.push(root_node()); | 899 work_queue.push(root_node()); |
| 899 while (!work_queue.empty()) { | 900 while (!work_queue.empty()) { |
| 900 node = work_queue.front(); | 901 node = work_queue.front(); |
| 901 work_queue.pop(); | 902 work_queue.pop(); |
| 902 | 903 |
| 903 // Enqueue any children and keep looking if the current node doesn't match. | 904 // Enqueue any children and keep looking if the current node doesn't match. |
| 904 if (!node->MatchesFrame(frame_tree_node)) { | 905 if (!node->MatchesFrame(frame_tree_node)) { |
| 905 for (auto* child : node->children) { | 906 for (const auto& child : node->children) { |
| 906 work_queue.push(child); | 907 work_queue.push(child.get()); |
| 907 } | 908 } |
| 908 continue; | 909 continue; |
| 909 } | 910 } |
| 910 | 911 |
| 911 // Remove the node from the tree if it is not in the same position in the | 912 // Remove the node from the tree if it is not in the same position in the |
| 912 // tree of FrameNavigationEntries and the FrameTree. | 913 // tree of FrameNavigationEntries and the FrameTree. |
| 913 if (!InSameTreePosition(frame_tree_node, node)) { | 914 if (!InSameTreePosition(frame_tree_node, node)) { |
| 914 NavigationEntryImpl::TreeNode* parent_node = node->parent; | 915 NavigationEntryImpl::TreeNode* parent_node = node->parent; |
| 915 auto it = std::find(parent_node->children.begin(), | 916 auto it = std::find_if( |
| 916 parent_node->children.end(), node); | 917 parent_node->children.begin(), parent_node->children.end(), |
| 918 [node](const std::unique_ptr<NavigationEntryImpl::TreeNode>& item) { |
| 919 return item.get() == node; |
| 920 }); |
| 917 CHECK(it != parent_node->children.end()); | 921 CHECK(it != parent_node->children.end()); |
| 918 parent_node->children.erase(it); | 922 parent_node->children.erase(it); |
| 919 } | 923 } |
| 920 ++count; | 924 ++count; |
| 921 } | 925 } |
| 922 | 926 |
| 923 // At most one match is expected, since it is based on unique frame name. | 927 // At most one match is expected, since it is based on unique frame name. |
| 924 DCHECK_LE(count, 1); | 928 DCHECK_LE(count, 1); |
| 925 } | 929 } |
| 926 | 930 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 940 NavigationEntryImpl::TreeNode* node = nullptr; | 944 NavigationEntryImpl::TreeNode* node = nullptr; |
| 941 std::queue<NavigationEntryImpl::TreeNode*> work_queue; | 945 std::queue<NavigationEntryImpl::TreeNode*> work_queue; |
| 942 work_queue.push(root_node()); | 946 work_queue.push(root_node()); |
| 943 while (!work_queue.empty()) { | 947 while (!work_queue.empty()) { |
| 944 node = work_queue.front(); | 948 node = work_queue.front(); |
| 945 work_queue.pop(); | 949 work_queue.pop(); |
| 946 if (node->MatchesFrame(frame_tree_node)) | 950 if (node->MatchesFrame(frame_tree_node)) |
| 947 return node; | 951 return node; |
| 948 | 952 |
| 949 // Enqueue any children and keep looking. | 953 // Enqueue any children and keep looking. |
| 950 for (auto* child : node->children) | 954 for (const auto& child : node->children) |
| 951 work_queue.push(child); | 955 work_queue.push(child.get()); |
| 952 } | 956 } |
| 953 return nullptr; | 957 return nullptr; |
| 954 } | 958 } |
| 955 | 959 |
| 956 } // namespace content | 960 } // namespace content |
| OLD | NEW |