| 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 |