blob: 413c775dd6ec30fad1e48bf80d3d0a8e3065c3be [file] [log] [blame]
[email protected]021b67d2014-04-22 00:57:271// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/*
6 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
7 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
9 * (http://www.torchmobile.com/)
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 *
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
21 * its contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
25 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
28 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#include "content/renderer/history_entry.h"
37
leon.han21e0e482017-02-23 04:13:3238#include <algorithm>
39
40#include "base/memory/ptr_util.h"
[email protected]021b67d2014-04-22 00:57:2741#include "content/renderer/render_frame_impl.h"
42#include "content/renderer/render_view_impl.h"
mlamouri862a2ed2014-09-10 15:14:5443#include "third_party/WebKit/public/web/WebLocalFrame.h"
[email protected]021b67d2014-04-22 00:57:2744
45using blink::WebFrame;
46using blink::WebHistoryItem;
47
48namespace content {
49
50HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::AddChild(
japhet740b2ff2015-06-02 00:46:0851 const WebHistoryItem& item) {
leon.han21e0e482017-02-23 04:13:3252 children_.push_back(base::MakeUnique<HistoryNode>(entry_, item));
53 return children_.back().get();
[email protected]021b67d2014-04-22 00:57:2754}
55
[email protected]9cd14ef2014-04-30 18:26:0356HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::AddChild() {
japhet740b2ff2015-06-02 00:46:0857 return AddChild(WebHistoryItem());
[email protected]9cd14ef2014-04-30 18:26:0358}
59
leon.han21e0e482017-02-23 04:13:3260std::unique_ptr<HistoryEntry::HistoryNode>
61HistoryEntry::HistoryNode::CloneAndReplace(
japhet740b2ff2015-06-02 00:46:0862 const base::WeakPtr<HistoryEntry>& new_entry,
[email protected]021b67d2014-04-22 00:57:2763 const WebHistoryItem& new_item,
64 bool clone_children_of_target,
65 RenderFrameImpl* target_frame,
66 RenderFrameImpl* current_frame) {
67 bool is_target_frame = target_frame == current_frame;
68 const WebHistoryItem& item_for_create = is_target_frame ? new_item : item_;
leon.han21e0e482017-02-23 04:13:3269 auto new_history_node =
70 base::MakeUnique<HistoryNode>(new_entry, item_for_create);
[email protected]021b67d2014-04-22 00:57:2771
creis225a7432016-06-03 22:56:2772 // Use the last committed history item for the frame rather than item_, since
73 // the latter may not accurately reflect which URL is currently committed in
74 // the frame. See https://crbug.com/612713#c12.
75 const WebHistoryItem& current_item = current_frame->current_history_item();
Blink Reformat1c4d759e2017-04-09 16:34:5476 if (is_target_frame && clone_children_of_target && !current_item.IsNull()) {
creis6f4792bc2016-06-23 17:05:2177 // TODO(creis): Setting the document sequence number here appears to be
78 // unnecessary. Remove this block if this DCHECK never fires.
Blink Reformat1c4d759e2017-04-09 16:34:5479 DCHECK_EQ(current_item.DocumentSequenceNumber(),
80 new_history_node->item().DocumentSequenceNumber());
[email protected]021b67d2014-04-22 00:57:2781 }
82
nasko4c0feb62015-06-05 18:37:0683 // TODO(creis): This needs to be updated to handle HistoryEntry in
84 // subframe processes, where the main frame isn't guaranteed to be in the
85 // same process.
86 if (current_frame && (clone_children_of_target || !is_target_frame)) {
Blink Reformat1c4d759e2017-04-09 16:34:5487 for (WebFrame* child = current_frame->GetWebFrame()->FirstChild(); child;
88 child = child->NextSibling()) {
[email protected]021b67d2014-04-22 00:57:2789 RenderFrameImpl* child_render_frame =
90 RenderFrameImpl::FromWebFrame(child);
creis0040d342015-02-19 01:42:3791 // TODO(creis): A child frame may be a RenderFrameProxy. We should still
92 // process its children, but that will be possible when we move this code
93 // to the browser process in https://crbug.com/236848.
94 if (!child_render_frame)
95 continue;
[email protected]021b67d2014-04-22 00:57:2796 HistoryNode* child_history_node =
97 entry_->GetHistoryNodeForFrame(child_render_frame);
98 if (!child_history_node)
99 continue;
leon.han21e0e482017-02-23 04:13:32100
101 new_history_node->children_.push_back(child_history_node->CloneAndReplace(
102 new_entry, new_item, clone_children_of_target, target_frame,
103 child_render_frame));
[email protected]021b67d2014-04-22 00:57:27104 }
105 }
106 return new_history_node;
107}
108
[email protected]9cd14ef2014-04-30 18:26:03109void HistoryEntry::HistoryNode::set_item(const WebHistoryItem& item) {
Blink Reformat1c4d759e2017-04-09 16:34:54110 DCHECK(!item.IsNull());
111 entry_->unique_names_to_items_[item.Target().Utf8()] = this;
112 unique_names_.push_back(item.Target().Utf8());
[email protected]9cd14ef2014-04-30 18:26:03113 item_ = item;
114}
115
japhet740b2ff2015-06-02 00:46:08116HistoryEntry::HistoryNode::HistoryNode(const base::WeakPtr<HistoryEntry>& entry,
117 const WebHistoryItem& item)
118 : entry_(entry) {
Blink Reformat1c4d759e2017-04-09 16:34:54119 if (!item.IsNull())
japhet740b2ff2015-06-02 00:46:08120 set_item(item);
[email protected]021b67d2014-04-22 00:57:27121}
122
123HistoryEntry::HistoryNode::~HistoryNode() {
Blink Reformat1c4d759e2017-04-09 16:34:54124 if (!entry_ || item_.IsNull())
japhet740b2ff2015-06-02 00:46:08125 return;
126
ki.stfu7cf10ca2015-09-27 08:37:01127 for (const std::string& name : unique_names_) {
japhet740b2ff2015-06-02 00:46:08128 if (entry_->unique_names_to_items_[name] == this)
129 entry_->unique_names_to_items_.erase(name);
130 }
[email protected]021b67d2014-04-22 00:57:27131}
132
leon.han21e0e482017-02-23 04:13:32133std::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
[email protected]021b67d2014-04-22 00:57:27144void HistoryEntry::HistoryNode::RemoveChildren() {
leon.han21e0e482017-02-23 04:13:32145 children_.clear();
[email protected]021b67d2014-04-22 00:57:27146}
147
japhet740b2ff2015-06-02 00:46:08148HistoryEntry::HistoryEntry() : weak_ptr_factory_(this) {
149 root_.reset(
150 new HistoryNode(weak_ptr_factory_.GetWeakPtr(), WebHistoryItem()));
[email protected]021b67d2014-04-22 00:57:27151}
152
153HistoryEntry::~HistoryEntry() {
154}
155
japhet740b2ff2015-06-02 00:46:08156HistoryEntry::HistoryEntry(const WebHistoryItem& root)
157 : weak_ptr_factory_(this) {
158 root_.reset(new HistoryNode(weak_ptr_factory_.GetWeakPtr(), root));
[email protected]021b67d2014-04-22 00:57:27159}
160
161HistoryEntry* HistoryEntry::CloneAndReplace(const WebHistoryItem& new_item,
162 bool clone_children_of_target,
163 RenderFrameImpl* target_frame,
164 RenderViewImpl* render_view) {
165 HistoryEntry* new_entry = new HistoryEntry();
leon.han21e0e482017-02-23 04:13:32166 new_entry->root_ =
japhet740b2ff2015-06-02 00:46:08167 root_->CloneAndReplace(new_entry->weak_ptr_factory_.GetWeakPtr(),
168 new_item, clone_children_of_target, target_frame,
leon.han21e0e482017-02-23 04:13:32169 render_view->GetMainRenderFrame());
[email protected]021b67d2014-04-22 00:57:27170 return new_entry;
171}
172
173HistoryEntry::HistoryNode* HistoryEntry::GetHistoryNodeForFrame(
174 RenderFrameImpl* frame) {
Blink Reformat1c4d759e2017-04-09 16:34:54175 if (!frame->GetWebFrame()->Parent())
japhet740b2ff2015-06-02 00:46:08176 return root_history_node();
Daniel Cheng999698bd2017-03-22 04:56:37177 return unique_names_to_items_[frame->unique_name()];
[email protected]021b67d2014-04-22 00:57:27178}
179
180WebHistoryItem HistoryEntry::GetItemForFrame(RenderFrameImpl* frame) {
181 if (HistoryNode* history_node = GetHistoryNodeForFrame(frame))
182 return history_node->item();
183 return WebHistoryItem();
184}
185
186} // namespace content