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 17 matching lines...) Expand all Loading... |
28 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 28 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
34 */ | 34 */ |
35 | 35 |
36 #include "content/renderer/history_entry.h" | 36 #include "content/renderer/history_entry.h" |
37 | 37 |
| 38 #include <algorithm> |
| 39 |
| 40 #include "base/memory/ptr_util.h" |
38 #include "content/renderer/render_frame_impl.h" | 41 #include "content/renderer/render_frame_impl.h" |
39 #include "content/renderer/render_view_impl.h" | 42 #include "content/renderer/render_view_impl.h" |
40 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 43 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
41 | 44 |
42 using blink::WebFrame; | 45 using blink::WebFrame; |
43 using blink::WebHistoryItem; | 46 using blink::WebHistoryItem; |
44 | 47 |
45 namespace content { | 48 namespace content { |
46 | 49 |
47 HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::AddChild( | 50 HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::AddChild( |
48 const WebHistoryItem& item) { | 51 const WebHistoryItem& item) { |
49 children_->push_back(new HistoryNode(entry_, item)); | 52 children_.push_back(base::MakeUnique<HistoryNode>(entry_, item)); |
50 return children_->back(); | 53 return children_.back().get(); |
51 } | 54 } |
52 | 55 |
53 HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::AddChild() { | 56 HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::AddChild() { |
54 return AddChild(WebHistoryItem()); | 57 return AddChild(WebHistoryItem()); |
55 } | 58 } |
56 | 59 |
57 HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::CloneAndReplace( | 60 std::unique_ptr<HistoryEntry::HistoryNode> |
| 61 HistoryEntry::HistoryNode::CloneAndReplace( |
58 const base::WeakPtr<HistoryEntry>& new_entry, | 62 const base::WeakPtr<HistoryEntry>& new_entry, |
59 const WebHistoryItem& new_item, | 63 const WebHistoryItem& new_item, |
60 bool clone_children_of_target, | 64 bool clone_children_of_target, |
61 RenderFrameImpl* target_frame, | 65 RenderFrameImpl* target_frame, |
62 RenderFrameImpl* current_frame) { | 66 RenderFrameImpl* current_frame) { |
63 bool is_target_frame = target_frame == current_frame; | 67 bool is_target_frame = target_frame == current_frame; |
64 const WebHistoryItem& item_for_create = is_target_frame ? new_item : item_; | 68 const WebHistoryItem& item_for_create = is_target_frame ? new_item : item_; |
65 HistoryNode* new_history_node = new HistoryNode(new_entry, item_for_create); | 69 auto new_history_node = |
| 70 base::MakeUnique<HistoryNode>(new_entry, item_for_create); |
66 | 71 |
67 // Use the last committed history item for the frame rather than item_, since | 72 // Use the last committed history item for the frame rather than item_, since |
68 // the latter may not accurately reflect which URL is currently committed in | 73 // the latter may not accurately reflect which URL is currently committed in |
69 // the frame. See https://crbug.com/612713#c12. | 74 // the frame. See https://crbug.com/612713#c12. |
70 const WebHistoryItem& current_item = current_frame->current_history_item(); | 75 const WebHistoryItem& current_item = current_frame->current_history_item(); |
71 if (is_target_frame && clone_children_of_target && !current_item.isNull()) { | 76 if (is_target_frame && clone_children_of_target && !current_item.isNull()) { |
72 // TODO(creis): Setting the document sequence number here appears to be | 77 // TODO(creis): Setting the document sequence number here appears to be |
73 // unnecessary. Remove this block if this DCHECK never fires. | 78 // unnecessary. Remove this block if this DCHECK never fires. |
74 DCHECK_EQ(current_item.documentSequenceNumber(), | 79 DCHECK_EQ(current_item.documentSequenceNumber(), |
75 new_history_node->item().documentSequenceNumber()); | 80 new_history_node->item().documentSequenceNumber()); |
76 } | 81 } |
77 | 82 |
78 // TODO(creis): This needs to be updated to handle HistoryEntry in | 83 // TODO(creis): This needs to be updated to handle HistoryEntry in |
79 // subframe processes, where the main frame isn't guaranteed to be in the | 84 // subframe processes, where the main frame isn't guaranteed to be in the |
80 // same process. | 85 // same process. |
81 if (current_frame && (clone_children_of_target || !is_target_frame)) { | 86 if (current_frame && (clone_children_of_target || !is_target_frame)) { |
82 for (WebFrame* child = current_frame->GetWebFrame()->firstChild(); child; | 87 for (WebFrame* child = current_frame->GetWebFrame()->firstChild(); child; |
83 child = child->nextSibling()) { | 88 child = child->nextSibling()) { |
84 RenderFrameImpl* child_render_frame = | 89 RenderFrameImpl* child_render_frame = |
85 RenderFrameImpl::FromWebFrame(child); | 90 RenderFrameImpl::FromWebFrame(child); |
86 // TODO(creis): A child frame may be a RenderFrameProxy. We should still | 91 // TODO(creis): A child frame may be a RenderFrameProxy. We should still |
87 // process its children, but that will be possible when we move this code | 92 // process its children, but that will be possible when we move this code |
88 // to the browser process in https://crbug.com/236848. | 93 // to the browser process in https://crbug.com/236848. |
89 if (!child_render_frame) | 94 if (!child_render_frame) |
90 continue; | 95 continue; |
91 HistoryNode* child_history_node = | 96 HistoryNode* child_history_node = |
92 entry_->GetHistoryNodeForFrame(child_render_frame); | 97 entry_->GetHistoryNodeForFrame(child_render_frame); |
93 if (!child_history_node) | 98 if (!child_history_node) |
94 continue; | 99 continue; |
95 HistoryNode* new_child_node = | 100 |
96 child_history_node->CloneAndReplace(new_entry, | 101 new_history_node->children_.push_back(child_history_node->CloneAndReplace( |
97 new_item, | 102 new_entry, new_item, clone_children_of_target, target_frame, |
98 clone_children_of_target, | 103 child_render_frame)); |
99 target_frame, | |
100 child_render_frame); | |
101 new_history_node->children_->push_back(new_child_node); | |
102 } | 104 } |
103 } | 105 } |
104 return new_history_node; | 106 return new_history_node; |
105 } | 107 } |
106 | 108 |
107 void HistoryEntry::HistoryNode::set_item(const WebHistoryItem& item) { | 109 void HistoryEntry::HistoryNode::set_item(const WebHistoryItem& item) { |
108 DCHECK(!item.isNull()); | 110 DCHECK(!item.isNull()); |
109 entry_->unique_names_to_items_[item.target().utf8()] = this; | 111 entry_->unique_names_to_items_[item.target().utf8()] = this; |
110 unique_names_.push_back(item.target().utf8()); | 112 unique_names_.push_back(item.target().utf8()); |
111 item_ = item; | 113 item_ = item; |
112 } | 114 } |
113 | 115 |
114 HistoryEntry::HistoryNode::HistoryNode(const base::WeakPtr<HistoryEntry>& entry, | 116 HistoryEntry::HistoryNode::HistoryNode(const base::WeakPtr<HistoryEntry>& entry, |
115 const WebHistoryItem& item) | 117 const WebHistoryItem& item) |
116 : entry_(entry) { | 118 : entry_(entry) { |
117 if (!item.isNull()) | 119 if (!item.isNull()) |
118 set_item(item); | 120 set_item(item); |
119 children_.reset(new ScopedVector<HistoryNode>); | |
120 } | 121 } |
121 | 122 |
122 HistoryEntry::HistoryNode::~HistoryNode() { | 123 HistoryEntry::HistoryNode::~HistoryNode() { |
123 if (!entry_ || item_.isNull()) | 124 if (!entry_ || item_.isNull()) |
124 return; | 125 return; |
125 | 126 |
126 for (const std::string& name : unique_names_) { | 127 for (const std::string& name : unique_names_) { |
127 if (entry_->unique_names_to_items_[name] == this) | 128 if (entry_->unique_names_to_items_[name] == this) |
128 entry_->unique_names_to_items_.erase(name); | 129 entry_->unique_names_to_items_.erase(name); |
129 } | 130 } |
130 } | 131 } |
131 | 132 |
| 133 std::vector<HistoryEntry::HistoryNode*> HistoryEntry::HistoryNode::children() |
| 134 const { |
| 135 std::vector<HistoryEntry::HistoryNode*> children(children_.size()); |
| 136 std::transform(children_.cbegin(), children_.cend(), children.begin(), |
| 137 [](const std::unique_ptr<HistoryEntry::HistoryNode>& item) { |
| 138 return item.get(); |
| 139 }); |
| 140 |
| 141 return children; |
| 142 } |
| 143 |
132 void HistoryEntry::HistoryNode::RemoveChildren() { | 144 void HistoryEntry::HistoryNode::RemoveChildren() { |
133 children_.reset(new ScopedVector<HistoryNode>); | 145 children_.clear(); |
134 } | 146 } |
135 | 147 |
136 HistoryEntry::HistoryEntry() : weak_ptr_factory_(this) { | 148 HistoryEntry::HistoryEntry() : weak_ptr_factory_(this) { |
137 root_.reset( | 149 root_.reset( |
138 new HistoryNode(weak_ptr_factory_.GetWeakPtr(), WebHistoryItem())); | 150 new HistoryNode(weak_ptr_factory_.GetWeakPtr(), WebHistoryItem())); |
139 } | 151 } |
140 | 152 |
141 HistoryEntry::~HistoryEntry() { | 153 HistoryEntry::~HistoryEntry() { |
142 } | 154 } |
143 | 155 |
144 HistoryEntry::HistoryEntry(const WebHistoryItem& root) | 156 HistoryEntry::HistoryEntry(const WebHistoryItem& root) |
145 : weak_ptr_factory_(this) { | 157 : weak_ptr_factory_(this) { |
146 root_.reset(new HistoryNode(weak_ptr_factory_.GetWeakPtr(), root)); | 158 root_.reset(new HistoryNode(weak_ptr_factory_.GetWeakPtr(), root)); |
147 } | 159 } |
148 | 160 |
149 HistoryEntry* HistoryEntry::CloneAndReplace(const WebHistoryItem& new_item, | 161 HistoryEntry* HistoryEntry::CloneAndReplace(const WebHistoryItem& new_item, |
150 bool clone_children_of_target, | 162 bool clone_children_of_target, |
151 RenderFrameImpl* target_frame, | 163 RenderFrameImpl* target_frame, |
152 RenderViewImpl* render_view) { | 164 RenderViewImpl* render_view) { |
153 HistoryEntry* new_entry = new HistoryEntry(); | 165 HistoryEntry* new_entry = new HistoryEntry(); |
154 new_entry->root_.reset( | 166 new_entry->root_ = |
155 root_->CloneAndReplace(new_entry->weak_ptr_factory_.GetWeakPtr(), | 167 root_->CloneAndReplace(new_entry->weak_ptr_factory_.GetWeakPtr(), |
156 new_item, clone_children_of_target, target_frame, | 168 new_item, clone_children_of_target, target_frame, |
157 render_view->GetMainRenderFrame())); | 169 render_view->GetMainRenderFrame()); |
158 return new_entry; | 170 return new_entry; |
159 } | 171 } |
160 | 172 |
161 HistoryEntry::HistoryNode* HistoryEntry::GetHistoryNodeForFrame( | 173 HistoryEntry::HistoryNode* HistoryEntry::GetHistoryNodeForFrame( |
162 RenderFrameImpl* frame) { | 174 RenderFrameImpl* frame) { |
163 if (!frame->GetWebFrame()->parent()) | 175 if (!frame->GetWebFrame()->parent()) |
164 return root_history_node(); | 176 return root_history_node(); |
165 return unique_names_to_items_[frame->GetWebFrame()->uniqueName().utf8()]; | 177 return unique_names_to_items_[frame->GetWebFrame()->uniqueName().utf8()]; |
166 } | 178 } |
167 | 179 |
168 WebHistoryItem HistoryEntry::GetItemForFrame(RenderFrameImpl* frame) { | 180 WebHistoryItem HistoryEntry::GetItemForFrame(RenderFrameImpl* frame) { |
169 if (HistoryNode* history_node = GetHistoryNodeForFrame(frame)) | 181 if (HistoryNode* history_node = GetHistoryNodeForFrame(frame)) |
170 return history_node->item(); | 182 return history_node->item(); |
171 return WebHistoryItem(); | 183 return WebHistoryItem(); |
172 } | 184 } |
173 | 185 |
174 } // namespace content | 186 } // namespace content |
OLD | NEW |