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
3 // found in the LICENSE file.
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/)
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
36 #include "content/renderer/history_entry.h"
38 #include "content/renderer/render_frame_impl.h"
39 #include "content/renderer/render_view_impl.h"
40 #include "third_party/WebKit/public/web/WebLocalFrame.h"
42 using blink::WebFrame
;
43 using blink::WebHistoryItem
;
47 HistoryEntry::HistoryNode
* HistoryEntry::HistoryNode::AddChild(
48 const WebHistoryItem
& item
) {
49 children_
->push_back(new HistoryNode(entry_
, item
));
50 return children_
->back();
53 HistoryEntry::HistoryNode
* HistoryEntry::HistoryNode::AddChild() {
54 return AddChild(WebHistoryItem());
57 HistoryEntry::HistoryNode
* HistoryEntry::HistoryNode::CloneAndReplace(
58 const base::WeakPtr
<HistoryEntry
>& new_entry
,
59 const WebHistoryItem
& new_item
,
60 bool clone_children_of_target
,
61 RenderFrameImpl
* target_frame
,
62 RenderFrameImpl
* current_frame
) {
63 bool is_target_frame
= target_frame
== current_frame
;
64 const WebHistoryItem
& item_for_create
= is_target_frame
? new_item
: item_
;
65 HistoryNode
* new_history_node
= new HistoryNode(new_entry
, item_for_create
);
67 if (is_target_frame
&& clone_children_of_target
&& !item_
.isNull()) {
68 new_history_node
->item().setDocumentSequenceNumber(
69 item_
.documentSequenceNumber());
72 // TODO(creis): This needs to be updated to handle HistoryEntry in
73 // subframe processes, where the main frame isn't guaranteed to be in the
75 if (current_frame
&& (clone_children_of_target
|| !is_target_frame
)) {
76 for (WebFrame
* child
= current_frame
->GetWebFrame()->firstChild(); child
;
77 child
= child
->nextSibling()) {
78 RenderFrameImpl
* child_render_frame
=
79 RenderFrameImpl::FromWebFrame(child
);
80 // TODO(creis): A child frame may be a RenderFrameProxy. We should still
81 // process its children, but that will be possible when we move this code
82 // to the browser process in https://crbug.com/236848.
83 if (!child_render_frame
)
85 HistoryNode
* child_history_node
=
86 entry_
->GetHistoryNodeForFrame(child_render_frame
);
87 if (!child_history_node
)
89 HistoryNode
* new_child_node
=
90 child_history_node
->CloneAndReplace(new_entry
,
92 clone_children_of_target
,
95 new_history_node
->children_
->push_back(new_child_node
);
98 return new_history_node
;
101 void HistoryEntry::HistoryNode::set_item(const WebHistoryItem
& item
) {
102 DCHECK(!item
.isNull());
103 entry_
->unique_names_to_items_
[item
.target().utf8()] = this;
104 unique_names_
.push_back(item
.target().utf8());
108 HistoryEntry::HistoryNode::HistoryNode(const base::WeakPtr
<HistoryEntry
>& entry
,
109 const WebHistoryItem
& item
)
113 children_
.reset(new ScopedVector
<HistoryNode
>);
116 HistoryEntry::HistoryNode::~HistoryNode() {
117 if (!entry_
|| item_
.isNull())
120 for (std::string name
: unique_names_
) {
121 if (entry_
->unique_names_to_items_
[name
] == this)
122 entry_
->unique_names_to_items_
.erase(name
);
126 void HistoryEntry::HistoryNode::RemoveChildren() {
127 children_
.reset(new ScopedVector
<HistoryNode
>);
130 HistoryEntry::HistoryEntry() : weak_ptr_factory_(this) {
132 new HistoryNode(weak_ptr_factory_
.GetWeakPtr(), WebHistoryItem()));
135 HistoryEntry::~HistoryEntry() {
138 HistoryEntry::HistoryEntry(const WebHistoryItem
& root
)
139 : weak_ptr_factory_(this) {
140 root_
.reset(new HistoryNode(weak_ptr_factory_
.GetWeakPtr(), root
));
143 HistoryEntry
* HistoryEntry::CloneAndReplace(const WebHistoryItem
& new_item
,
144 bool clone_children_of_target
,
145 RenderFrameImpl
* target_frame
,
146 RenderViewImpl
* render_view
) {
147 HistoryEntry
* new_entry
= new HistoryEntry();
148 new_entry
->root_
.reset(
149 root_
->CloneAndReplace(new_entry
->weak_ptr_factory_
.GetWeakPtr(),
150 new_item
, clone_children_of_target
, target_frame
,
151 render_view
->GetMainRenderFrame()));
155 HistoryEntry::HistoryNode
* HistoryEntry::GetHistoryNodeForFrame(
156 RenderFrameImpl
* frame
) {
157 if (!frame
->GetWebFrame()->parent())
158 return root_history_node();
159 return unique_names_to_items_
[frame
->GetWebFrame()->uniqueName().utf8()];
162 WebHistoryItem
HistoryEntry::GetItemForFrame(RenderFrameImpl
* frame
) {
163 if (HistoryNode
* history_node
= GetHistoryNodeForFrame(frame
))
164 return history_node
->item();
165 return WebHistoryItem();
168 } // namespace content