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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
59 int64_t frame_id) { | 59 int64_t frame_id) { |
60 children_->push_back(new HistoryNode(entry_, item, frame_id)); | 60 children_->push_back(new HistoryNode(entry_, item, frame_id)); |
61 return children_->back(); | 61 return children_->back(); |
62 } | 62 } |
63 | 63 |
64 HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::AddChild() { | 64 HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::AddChild() { |
65 return AddChild(WebHistoryItem(), kInvalidFrameRoutingID); | 65 return AddChild(WebHistoryItem(), kInvalidFrameRoutingID); |
66 } | 66 } |
67 | 67 |
68 HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::CloneAndReplace( | 68 HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::CloneAndReplace( |
69 HistoryEntry* new_entry, | 69 const base::WeakPtr<HistoryEntry>& new_entry, |
70 const WebHistoryItem& new_item, | 70 const WebHistoryItem& new_item, |
71 bool clone_children_of_target, | 71 bool clone_children_of_target, |
72 RenderFrameImpl* target_frame, | 72 RenderFrameImpl* target_frame, |
73 RenderFrameImpl* current_frame) { | 73 RenderFrameImpl* current_frame) { |
74 bool is_target_frame = target_frame == current_frame; | 74 bool is_target_frame = target_frame == current_frame; |
75 const WebHistoryItem& item_for_create = is_target_frame ? new_item : item_; | 75 const WebHistoryItem& item_for_create = is_target_frame ? new_item : item_; |
76 HistoryNode* new_history_node = new HistoryNode( | 76 HistoryNode* new_history_node = new HistoryNode( |
77 new_entry, item_for_create, current_frame->GetRoutingID()); | 77 new_entry, item_for_create, current_frame->GetRoutingID()); |
78 | 78 |
79 if (is_target_frame && clone_children_of_target && !item_.isNull()) { | 79 if (is_target_frame && clone_children_of_target && !item_.isNull()) { |
(...skipping 20 matching lines...) Expand all Loading... | |
100 new_item, | 100 new_item, |
101 clone_children_of_target, | 101 clone_children_of_target, |
102 target_frame, | 102 target_frame, |
103 child_render_frame); | 103 child_render_frame); |
104 new_history_node->children_->push_back(new_child_node); | 104 new_history_node->children_->push_back(new_child_node); |
105 } | 105 } |
106 } | 106 } |
107 return new_history_node; | 107 return new_history_node; |
108 } | 108 } |
109 | 109 |
110 void HistoryEntry::HistoryNode::set_item(const WebHistoryItem& item) { | 110 void HistoryEntry::HistoryNode::set_item(const WebHistoryItem& item) { |
Charlie Reis
2015/05/13 21:33:37
Can this be called more than once per HistoryNode?
Nate Chapin
2015/05/13 23:23:21
I would have confidently said "only once per node"
| |
111 // The previous HistoryItem might not have had a target set, or it might be | 111 // The previous HistoryItem might not have had a target set, or it might be |
112 // different than the current one. | 112 // different than the current one. |
113 entry_->unique_names_to_items_[item.target().utf8()] = this; | 113 entry_->unique_names_to_items_[item.target().utf8()] = this; |
114 unique_names_.push_back(item.target().utf8()); | |
115 | |
114 entry_->frames_to_items_[item.frameSequenceNumber()] = this; | 116 entry_->frames_to_items_[item.frameSequenceNumber()] = this; |
117 frame_ids_.push_back(item.frameSequenceNumber()); | |
118 | |
115 item_ = item; | 119 item_ = item; |
116 } | 120 } |
117 | 121 |
118 HistoryEntry::HistoryNode::HistoryNode(HistoryEntry* entry, | 122 HistoryEntry::HistoryNode::HistoryNode( |
119 const WebHistoryItem& item, | 123 const base::WeakPtr<HistoryEntry>& entry, const WebHistoryItem& item, |
120 int64_t frame_id) | 124 int64_t frame_id) |
121 : entry_(entry), item_(item) { | 125 : entry_(entry), item_(item) { |
122 if (frame_id != kInvalidFrameRoutingID) { | 126 if (frame_id != kInvalidFrameRoutingID) { |
123 // Each history item is given a frame sequence number on creation. | 127 // Each history item is given a frame sequence number on creation. |
124 // If we've already mapped this frame id to a sequence number, standardize | 128 // If we've already mapped this frame id to a sequence number, standardize |
125 // this item to that sequence number. Otherwise, map the frame id to this | 129 // this item to that sequence number. Otherwise, map the frame id to this |
126 // item's existing sequence number. | 130 // item's existing sequence number. |
127 if (GetFrameMap()[frame_id] == 0) | 131 if (GetFrameMap()[frame_id] == 0) |
128 GetFrameMap()[frame_id] = item_.frameSequenceNumber(); | 132 GetFrameMap()[frame_id] = item_.frameSequenceNumber(); |
129 else if (!item_.isNull()) | 133 else if (!item_.isNull()) |
130 item_.setFrameSequenceNumber(GetFrameMap()[frame_id]); | 134 item_.setFrameSequenceNumber(GetFrameMap()[frame_id]); |
131 entry_->frames_to_items_[GetFrameMap()[frame_id]] = this; | 135 entry_->frames_to_items_[GetFrameMap()[frame_id]] = this; |
136 frame_ids_.push_back(GetFrameMap()[frame_id]); | |
132 } | 137 } |
133 | 138 |
134 if (!item_.isNull()) | 139 if (!item_.isNull()) { |
135 entry_->unique_names_to_items_[item_.target().utf8()] = this; | 140 entry_->unique_names_to_items_[item_.target().utf8()] = this; |
141 unique_names_.push_back(item.target().utf8()); | |
142 } | |
136 children_.reset(new ScopedVector<HistoryNode>); | 143 children_.reset(new ScopedVector<HistoryNode>); |
137 } | 144 } |
138 | 145 |
139 HistoryEntry::HistoryNode::~HistoryNode() { | 146 HistoryEntry::HistoryNode::~HistoryNode() { |
147 if (!entry_) | |
148 return; | |
149 | |
150 for (uint64_t id : frame_ids_) { | |
151 HistoryEntry::FramesToItems::iterator it = | |
152 entry_->frames_to_items_.find(id); | |
153 if (it != entry_->frames_to_items_.end() && it->second == this) | |
154 entry_->frames_to_items_.erase(id); | |
Charlie Reis
2015/05/13 21:33:37
nit: Wrong indent. (git cl format can help.)
Nate Chapin
2015/05/13 23:23:21
Done.
| |
155 } | |
156 | |
157 for (std::string name : unique_names_) { | |
158 HistoryEntry::UniqueNamesToItems::iterator it = | |
159 entry_->unique_names_to_items_.find(name); | |
160 if (it != entry_->unique_names_to_items_.end() && it->second == this) | |
161 entry_->unique_names_to_items_.erase(name); | |
162 } | |
140 } | 163 } |
141 | 164 |
142 void HistoryEntry::HistoryNode::RemoveChildren() { | 165 void HistoryEntry::HistoryNode::RemoveChildren() { |
143 // TODO(japhet): This is inefficient. Figure out a cleaner way to ensure | |
144 // this HistoryNode isn't cached anywhere. | |
145 std::vector<uint64_t> frames_to_remove; | |
146 std::vector<std::string> unique_names_to_remove; | |
147 for (size_t i = 0; i < children().size(); i++) { | |
148 children().at(i)->RemoveChildren(); | |
149 | |
150 HistoryEntry::FramesToItems::iterator frames_end = | |
151 entry_->frames_to_items_.end(); | |
152 HistoryEntry::UniqueNamesToItems::iterator unique_names_end = | |
153 entry_->unique_names_to_items_.end(); | |
154 for (HistoryEntry::FramesToItems::iterator it = | |
155 entry_->frames_to_items_.begin(); | |
156 it != frames_end; | |
157 ++it) { | |
158 if (it->second == children().at(i)) | |
159 frames_to_remove.push_back(GetFrameMap()[it->first]); | |
160 } | |
161 for (HistoryEntry::UniqueNamesToItems::iterator it = | |
162 entry_->unique_names_to_items_.begin(); | |
163 it != unique_names_end; | |
164 ++it) { | |
165 if (it->second == children().at(i)) | |
166 unique_names_to_remove.push_back(it->first); | |
167 } | |
168 } | |
169 for (unsigned i = 0; i < frames_to_remove.size(); i++) | |
170 entry_->frames_to_items_.erase(frames_to_remove[i]); | |
171 for (unsigned i = 0; i < unique_names_to_remove.size(); i++) | |
172 entry_->unique_names_to_items_.erase(unique_names_to_remove[i]); | |
173 children_.reset(new ScopedVector<HistoryNode>); | 166 children_.reset(new ScopedVector<HistoryNode>); |
174 } | 167 } |
175 | 168 |
176 HistoryEntry::HistoryEntry() { | 169 HistoryEntry::HistoryEntry() |
177 root_.reset(new HistoryNode(this, WebHistoryItem(), kInvalidFrameRoutingID)); | 170 : weak_ptr_factory_(this) { |
171 root_.reset(new HistoryNode(weak_ptr_factory_.GetWeakPtr(), | |
172 WebHistoryItem(), | |
173 kInvalidFrameRoutingID)); | |
178 } | 174 } |
179 | 175 |
180 HistoryEntry::~HistoryEntry() { | 176 HistoryEntry::~HistoryEntry() { |
181 } | 177 } |
182 | 178 |
183 HistoryEntry::HistoryEntry(const WebHistoryItem& root, int64_t frame_id) { | 179 HistoryEntry::HistoryEntry(const WebHistoryItem& root, int64_t frame_id) |
184 root_.reset(new HistoryNode(this, root, frame_id)); | 180 : weak_ptr_factory_(this) { |
181 root_.reset(new HistoryNode(weak_ptr_factory_.GetWeakPtr(), root, frame_id)); | |
185 } | 182 } |
186 | 183 |
187 HistoryEntry* HistoryEntry::CloneAndReplace(const WebHistoryItem& new_item, | 184 HistoryEntry* HistoryEntry::CloneAndReplace(const WebHistoryItem& new_item, |
188 bool clone_children_of_target, | 185 bool clone_children_of_target, |
189 RenderFrameImpl* target_frame, | 186 RenderFrameImpl* target_frame, |
190 RenderViewImpl* render_view) { | 187 RenderViewImpl* render_view) { |
191 HistoryEntry* new_entry = new HistoryEntry(); | 188 HistoryEntry* new_entry = new HistoryEntry(); |
192 new_entry->root_.reset( | 189 new_entry->root_.reset( |
193 root_->CloneAndReplace(new_entry, | 190 root_->CloneAndReplace(new_entry->weak_ptr_factory_.GetWeakPtr(), |
194 new_item, | 191 new_item, |
195 clone_children_of_target, | 192 clone_children_of_target, |
196 target_frame, | 193 target_frame, |
197 render_view->GetMainRenderFrame())); | 194 render_view->GetMainRenderFrame())); |
198 return new_entry; | 195 return new_entry; |
199 } | 196 } |
200 | 197 |
201 HistoryEntry::HistoryNode* HistoryEntry::GetHistoryNodeForFrame( | 198 HistoryEntry::HistoryNode* HistoryEntry::GetHistoryNodeForFrame( |
202 RenderFrameImpl* frame) { | 199 RenderFrameImpl* frame) { |
203 if (HistoryNode* history_node = | 200 if (HistoryNode* history_node = |
204 frames_to_items_[GetFrameMap()[frame->GetRoutingID()]]) | 201 frames_to_items_[GetFrameMap()[frame->GetRoutingID()]]) |
205 return history_node; | 202 return history_node; |
206 return unique_names_to_items_[frame->GetWebFrame()->uniqueName().utf8()]; | 203 return unique_names_to_items_[frame->GetWebFrame()->uniqueName().utf8()]; |
207 } | 204 } |
208 | 205 |
209 WebHistoryItem HistoryEntry::GetItemForFrame(RenderFrameImpl* frame) { | 206 WebHistoryItem HistoryEntry::GetItemForFrame(RenderFrameImpl* frame) { |
210 if (HistoryNode* history_node = GetHistoryNodeForFrame(frame)) | 207 if (HistoryNode* history_node = GetHistoryNodeForFrame(frame)) |
211 return history_node->item(); | 208 return history_node->item(); |
212 return WebHistoryItem(); | 209 return WebHistoryItem(); |
213 } | 210 } |
214 | 211 |
215 } // namespace content | 212 } // namespace content |
OLD | NEW |