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