OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 /* | 5 /* |
6 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | 6 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
7 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 7 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
9 * (http://www.torchmobile.com/) | 9 * (http://www.torchmobile.com/) |
10 * | 10 * |
(...skipping 26 matching lines...) Expand all Loading... |
37 | 37 |
38 #include "content/renderer/render_frame_impl.h" | 38 #include "content/renderer/render_frame_impl.h" |
39 #include "content/renderer/render_view_impl.h" | 39 #include "content/renderer/render_view_impl.h" |
40 #include "third_party/WebKit/public/web/WebFrame.h" | 40 #include "third_party/WebKit/public/web/WebFrame.h" |
41 | 41 |
42 using blink::WebFrame; | 42 using blink::WebFrame; |
43 using blink::WebHistoryItem; | 43 using blink::WebHistoryItem; |
44 | 44 |
45 namespace content { | 45 namespace content { |
46 | 46 |
| 47 // Frame routing ids are not safe to serialize, so instead create a mapping |
| 48 // from routing ids to frame sequence numbers. The sequence numbers can be |
| 49 // benignly serialized with limited risk of collision in a different process. |
| 50 // FrameMap is a singleton per-process. |
| 51 typedef base::hash_map<uint64_t, uint64_t> FrameMap; |
| 52 static FrameMap& GetFrameMap() { |
| 53 CR_DEFINE_STATIC_LOCAL(FrameMap, routing_ids_to_internal_frame_ids, ()); |
| 54 return routing_ids_to_internal_frame_ids; |
| 55 } |
| 56 |
47 HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::AddChild( | 57 HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::AddChild( |
48 const WebHistoryItem& item, | 58 const WebHistoryItem& item, |
49 int64_t frame_id) { | 59 int64_t frame_id) { |
50 children_->push_back(new HistoryNode(entry_, item, frame_id)); | 60 children_->push_back(new HistoryNode(entry_, item, frame_id)); |
51 return children_->back(); | 61 return children_->back(); |
52 } | 62 } |
53 | 63 |
54 HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::AddChild() { | 64 HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::AddChild() { |
55 return AddChild(WebHistoryItem(), kInvalidFrameRoutingID); | 65 return AddChild(WebHistoryItem(), kInvalidFrameRoutingID); |
56 } | 66 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 new_history_node->children_->push_back(new_child_node); | 99 new_history_node->children_->push_back(new_child_node); |
90 } | 100 } |
91 } | 101 } |
92 return new_history_node; | 102 return new_history_node; |
93 } | 103 } |
94 | 104 |
95 void HistoryEntry::HistoryNode::set_item(const WebHistoryItem& item) { | 105 void HistoryEntry::HistoryNode::set_item(const WebHistoryItem& item) { |
96 // The previous HistoryItem might not have had a target set, or it might be | 106 // The previous HistoryItem might not have had a target set, or it might be |
97 // different than the current one. | 107 // different than the current one. |
98 entry_->unique_names_to_items_[item.target().utf8()] = this; | 108 entry_->unique_names_to_items_[item.target().utf8()] = this; |
| 109 entry_->frames_to_items_[item.frameSequenceNumber()] = this; |
99 item_ = item; | 110 item_ = item; |
100 } | 111 } |
101 | 112 |
102 HistoryEntry::HistoryNode::HistoryNode(HistoryEntry* entry, | 113 HistoryEntry::HistoryNode::HistoryNode(HistoryEntry* entry, |
103 const WebHistoryItem& item, | 114 const WebHistoryItem& item, |
104 int64_t frame_id) | 115 int64_t frame_id) |
105 : entry_(entry), item_(item) { | 116 : entry_(entry), item_(item) { |
106 if (frame_id != kInvalidFrameRoutingID) | 117 if (frame_id != kInvalidFrameRoutingID) { |
107 entry_->frames_to_items_[frame_id] = this; | 118 // Each history item is given a frame sequence number on creation. |
108 if (!item.isNull()) | 119 // If we've already mapped this frame id to a sequence number, standardize |
109 entry_->unique_names_to_items_[item.target().utf8()] = this; | 120 // this item to that sequence number. Otherwise, map the frame id to this |
| 121 // item's existing sequence number. |
| 122 if (GetFrameMap()[frame_id] == 0) |
| 123 GetFrameMap()[frame_id] = item_.frameSequenceNumber(); |
| 124 else if (!item_.isNull()) |
| 125 item_.setFrameSequenceNumber(GetFrameMap()[frame_id]); |
| 126 entry_->frames_to_items_[GetFrameMap()[frame_id]] = this; |
| 127 } |
| 128 |
| 129 if (!item_.isNull()) |
| 130 entry_->unique_names_to_items_[item_.target().utf8()] = this; |
110 children_.reset(new ScopedVector<HistoryNode>); | 131 children_.reset(new ScopedVector<HistoryNode>); |
111 } | 132 } |
112 | 133 |
113 HistoryEntry::HistoryNode::~HistoryNode() { | 134 HistoryEntry::HistoryNode::~HistoryNode() { |
114 } | 135 } |
115 | 136 |
116 void HistoryEntry::HistoryNode::RemoveChildren() { | 137 void HistoryEntry::HistoryNode::RemoveChildren() { |
117 // TODO(japhet): This is inefficient. Figure out a cleaner way to ensure | 138 // TODO(japhet): This is inefficient. Figure out a cleaner way to ensure |
118 // this HistoryNode isn't cached anywhere. | 139 // this HistoryNode isn't cached anywhere. |
119 std::vector<uint64_t> frames_to_remove; | 140 std::vector<uint64_t> frames_to_remove; |
120 std::vector<std::string> unique_names_to_remove; | 141 std::vector<std::string> unique_names_to_remove; |
121 for (size_t i = 0; i < children().size(); i++) { | 142 for (size_t i = 0; i < children().size(); i++) { |
122 children().at(i)->RemoveChildren(); | 143 children().at(i)->RemoveChildren(); |
123 | 144 |
124 HistoryEntry::FramesToItems::iterator frames_end = | 145 HistoryEntry::FramesToItems::iterator frames_end = |
125 entry_->frames_to_items_.end(); | 146 entry_->frames_to_items_.end(); |
126 HistoryEntry::UniqueNamesToItems::iterator unique_names_end = | 147 HistoryEntry::UniqueNamesToItems::iterator unique_names_end = |
127 entry_->unique_names_to_items_.end(); | 148 entry_->unique_names_to_items_.end(); |
128 for (HistoryEntry::FramesToItems::iterator it = | 149 for (HistoryEntry::FramesToItems::iterator it = |
129 entry_->frames_to_items_.begin(); | 150 entry_->frames_to_items_.begin(); |
130 it != frames_end; | 151 it != frames_end; |
131 ++it) { | 152 ++it) { |
132 if (it->second == children().at(i)) | 153 if (it->second == children().at(i)) |
133 frames_to_remove.push_back(it->first); | 154 frames_to_remove.push_back(GetFrameMap()[it->first]); |
134 } | 155 } |
135 for (HistoryEntry::UniqueNamesToItems::iterator it = | 156 for (HistoryEntry::UniqueNamesToItems::iterator it = |
136 entry_->unique_names_to_items_.begin(); | 157 entry_->unique_names_to_items_.begin(); |
137 it != unique_names_end; | 158 it != unique_names_end; |
138 ++it) { | 159 ++it) { |
139 if (it->second == children().at(i)) | 160 if (it->second == children().at(i)) |
140 unique_names_to_remove.push_back(it->first); | 161 unique_names_to_remove.push_back(it->first); |
141 } | 162 } |
142 } | 163 } |
143 for (unsigned i = 0; i < frames_to_remove.size(); i++) | 164 for (unsigned i = 0; i < frames_to_remove.size(); i++) |
(...skipping 23 matching lines...) Expand all Loading... |
167 root_->CloneAndReplace(new_entry, | 188 root_->CloneAndReplace(new_entry, |
168 new_item, | 189 new_item, |
169 clone_children_of_target, | 190 clone_children_of_target, |
170 target_frame, | 191 target_frame, |
171 render_view->main_render_frame())); | 192 render_view->main_render_frame())); |
172 return new_entry; | 193 return new_entry; |
173 } | 194 } |
174 | 195 |
175 HistoryEntry::HistoryNode* HistoryEntry::GetHistoryNodeForFrame( | 196 HistoryEntry::HistoryNode* HistoryEntry::GetHistoryNodeForFrame( |
176 RenderFrameImpl* frame) { | 197 RenderFrameImpl* frame) { |
177 if (HistoryNode* history_node = frames_to_items_[frame->GetRoutingID()]) | 198 if (HistoryNode* history_node = |
| 199 frames_to_items_[GetFrameMap()[frame->GetRoutingID()]]) |
178 return history_node; | 200 return history_node; |
179 return unique_names_to_items_[frame->GetWebFrame()->uniqueName().utf8()]; | 201 return unique_names_to_items_[frame->GetWebFrame()->uniqueName().utf8()]; |
180 } | 202 } |
181 | 203 |
182 WebHistoryItem HistoryEntry::GetItemForFrame(RenderFrameImpl* frame) { | 204 WebHistoryItem HistoryEntry::GetItemForFrame(RenderFrameImpl* frame) { |
183 if (HistoryNode* history_node = GetHistoryNodeForFrame(frame)) | 205 if (HistoryNode* history_node = GetHistoryNodeForFrame(frame)) |
184 return history_node->item(); | 206 return history_node->item(); |
185 return WebHistoryItem(); | 207 return WebHistoryItem(); |
186 } | 208 } |
187 | 209 |
188 } // namespace content | 210 } // namespace content |
OLD | NEW |