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 |