Index: content/renderer/history_entry.cc |
diff --git a/content/renderer/history_entry.cc b/content/renderer/history_entry.cc |
index 7686165f4eea2c131e1cb51a800383429b6277f9..efd6fb54682e43d22d18aab7eaa5a9adcf0b9ead 100644 |
--- a/content/renderer/history_entry.cc |
+++ b/content/renderer/history_entry.cc |
@@ -44,37 +44,25 @@ using blink::WebHistoryItem; |
namespace content { |
-// Frame routing ids are not safe to serialize, so instead create a mapping |
-// from routing ids to frame sequence numbers. The sequence numbers can be |
-// benignly serialized with limited risk of collision in a different process. |
-// FrameMap is a singleton per-process. |
-typedef base::hash_map<uint64_t, uint64_t> FrameMap; |
-static FrameMap& GetFrameMap() { |
- CR_DEFINE_STATIC_LOCAL(FrameMap, routing_ids_to_internal_frame_ids, ()); |
- return routing_ids_to_internal_frame_ids; |
-} |
- |
HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::AddChild( |
- const WebHistoryItem& item, |
- int64_t frame_id) { |
- children_->push_back(new HistoryNode(entry_, item, frame_id)); |
+ const WebHistoryItem& item) { |
+ children_->push_back(new HistoryNode(entry_, item)); |
return children_->back(); |
} |
HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::AddChild() { |
- return AddChild(WebHistoryItem(), kInvalidFrameRoutingID); |
+ return AddChild(WebHistoryItem()); |
} |
HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::CloneAndReplace( |
- HistoryEntry* new_entry, |
+ const base::WeakPtr<HistoryEntry>& new_entry, |
const WebHistoryItem& new_item, |
bool clone_children_of_target, |
RenderFrameImpl* target_frame, |
RenderFrameImpl* current_frame) { |
bool is_target_frame = target_frame == current_frame; |
const WebHistoryItem& item_for_create = is_target_frame ? new_item : item_; |
- HistoryNode* new_history_node = new HistoryNode( |
- new_entry, item_for_create, current_frame->GetRoutingID()); |
+ HistoryNode* new_history_node = new HistoryNode(new_entry, item_for_create); |
if (is_target_frame && clone_children_of_target && !item_.isNull()) { |
new_history_node->item().setDocumentSequenceNumber( |
@@ -108,80 +96,45 @@ HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::CloneAndReplace( |
} |
void HistoryEntry::HistoryNode::set_item(const WebHistoryItem& item) { |
- // The previous HistoryItem might not have had a target set, or it might be |
- // different than the current one. |
+ DCHECK(!item.isNull()); |
entry_->unique_names_to_items_[item.target().utf8()] = this; |
- entry_->frames_to_items_[item.frameSequenceNumber()] = this; |
+ unique_names_.push_back(item.target().utf8()); |
item_ = item; |
} |
-HistoryEntry::HistoryNode::HistoryNode(HistoryEntry* entry, |
- const WebHistoryItem& item, |
- int64_t frame_id) |
- : entry_(entry), item_(item) { |
- if (frame_id != kInvalidFrameRoutingID) { |
- // Each history item is given a frame sequence number on creation. |
- // If we've already mapped this frame id to a sequence number, standardize |
- // this item to that sequence number. Otherwise, map the frame id to this |
- // item's existing sequence number. |
- if (GetFrameMap()[frame_id] == 0) |
- GetFrameMap()[frame_id] = item_.frameSequenceNumber(); |
- else if (!item_.isNull()) |
- item_.setFrameSequenceNumber(GetFrameMap()[frame_id]); |
- entry_->frames_to_items_[GetFrameMap()[frame_id]] = this; |
- } |
- |
- if (!item_.isNull()) |
- entry_->unique_names_to_items_[item_.target().utf8()] = this; |
+HistoryEntry::HistoryNode::HistoryNode(const base::WeakPtr<HistoryEntry>& entry, |
+ const WebHistoryItem& item) |
+ : entry_(entry) { |
+ if (!item.isNull()) |
+ set_item(item); |
children_.reset(new ScopedVector<HistoryNode>); |
} |
HistoryEntry::HistoryNode::~HistoryNode() { |
+ if (!entry_ || item_.isNull()) |
+ return; |
+ |
+ for (std::string name : unique_names_) { |
+ if (entry_->unique_names_to_items_[name] == this) |
+ entry_->unique_names_to_items_.erase(name); |
+ } |
} |
void HistoryEntry::HistoryNode::RemoveChildren() { |
- // TODO(japhet): This is inefficient. Figure out a cleaner way to ensure |
- // this HistoryNode isn't cached anywhere. |
- std::vector<uint64_t> frames_to_remove; |
- std::vector<std::string> unique_names_to_remove; |
- for (size_t i = 0; i < children().size(); i++) { |
- children().at(i)->RemoveChildren(); |
- |
- HistoryEntry::FramesToItems::iterator frames_end = |
- entry_->frames_to_items_.end(); |
- HistoryEntry::UniqueNamesToItems::iterator unique_names_end = |
- entry_->unique_names_to_items_.end(); |
- for (HistoryEntry::FramesToItems::iterator it = |
- entry_->frames_to_items_.begin(); |
- it != frames_end; |
- ++it) { |
- if (it->second == children().at(i)) |
- frames_to_remove.push_back(GetFrameMap()[it->first]); |
- } |
- for (HistoryEntry::UniqueNamesToItems::iterator it = |
- entry_->unique_names_to_items_.begin(); |
- it != unique_names_end; |
- ++it) { |
- if (it->second == children().at(i)) |
- unique_names_to_remove.push_back(it->first); |
- } |
- } |
- for (unsigned i = 0; i < frames_to_remove.size(); i++) |
- entry_->frames_to_items_.erase(frames_to_remove[i]); |
- for (unsigned i = 0; i < unique_names_to_remove.size(); i++) |
- entry_->unique_names_to_items_.erase(unique_names_to_remove[i]); |
children_.reset(new ScopedVector<HistoryNode>); |
} |
-HistoryEntry::HistoryEntry() { |
- root_.reset(new HistoryNode(this, WebHistoryItem(), kInvalidFrameRoutingID)); |
+HistoryEntry::HistoryEntry() : weak_ptr_factory_(this) { |
+ root_.reset( |
+ new HistoryNode(weak_ptr_factory_.GetWeakPtr(), WebHistoryItem())); |
} |
HistoryEntry::~HistoryEntry() { |
} |
-HistoryEntry::HistoryEntry(const WebHistoryItem& root, int64_t frame_id) { |
- root_.reset(new HistoryNode(this, root, frame_id)); |
+HistoryEntry::HistoryEntry(const WebHistoryItem& root) |
+ : weak_ptr_factory_(this) { |
+ root_.reset(new HistoryNode(weak_ptr_factory_.GetWeakPtr(), root)); |
} |
HistoryEntry* HistoryEntry::CloneAndReplace(const WebHistoryItem& new_item, |
@@ -190,19 +143,16 @@ HistoryEntry* HistoryEntry::CloneAndReplace(const WebHistoryItem& new_item, |
RenderViewImpl* render_view) { |
HistoryEntry* new_entry = new HistoryEntry(); |
new_entry->root_.reset( |
- root_->CloneAndReplace(new_entry, |
- new_item, |
- clone_children_of_target, |
- target_frame, |
+ root_->CloneAndReplace(new_entry->weak_ptr_factory_.GetWeakPtr(), |
+ new_item, clone_children_of_target, target_frame, |
render_view->GetMainRenderFrame())); |
return new_entry; |
} |
HistoryEntry::HistoryNode* HistoryEntry::GetHistoryNodeForFrame( |
RenderFrameImpl* frame) { |
- if (HistoryNode* history_node = |
- frames_to_items_[GetFrameMap()[frame->GetRoutingID()]]) |
- return history_node; |
+ if (!frame->GetWebFrame()->parent()) |
+ return root_history_node(); |
return unique_names_to_items_[frame->GetWebFrame()->uniqueName().utf8()]; |
} |