1a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// found in the LICENSE file.
4a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
5a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch/*
6a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
7a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
8a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
9a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch *     (http://www.torchmobile.com/)
10a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch *
11a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * Redistribution and use in source and binary forms, with or without
12a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * modification, are permitted provided that the following conditions
13a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * are met:
14a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch *
15a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * 1.  Redistributions of source code must retain the above copyright
16a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch *     notice, this list of conditions and the following disclaimer.
17a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * 2.  Redistributions in binary form must reproduce the above copyright
18a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch *     notice, this list of conditions and the following disclaimer in the
19a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch *     documentation and/or other materials provided with the distribution.
20a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
21a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch *     its contributors may be used to endorse or promote products derived
22a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch *     from this software without specific prior written permission.
23a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch *
24a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
25a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
28a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch */
35a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
36a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "content/renderer/history_controller.h"
37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
38a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "content/renderer/render_frame_impl.h"
39a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "content/renderer/render_view_impl.h"
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/WebKit/public/web/WebLocalFrame.h"
41a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
42a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochusing blink::WebFrame;
43a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochusing blink::WebHistoryCommitType;
44a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochusing blink::WebHistoryItem;
45a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochusing blink::WebURLRequest;
46a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
47a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochnamespace content {
48a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
49a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochHistoryController::HistoryController(RenderViewImpl* render_view)
50a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    : render_view_(render_view) {
51a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
52a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
53a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochHistoryController::~HistoryController() {
54a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
55a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid HistoryController::GoToEntry(scoped_ptr<HistoryEntry> target_entry,
57a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                  WebURLRequest::CachePolicy cache_policy) {
58a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  HistoryFrameLoadVector same_document_loads;
59a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  HistoryFrameLoadVector different_document_loads;
60a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  provisional_entry_ = target_entry.Pass();
62a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WebFrame* main_frame = render_view_->GetMainRenderFrame()->GetWebFrame();
64a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (current_entry_) {
65a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RecursiveGoToEntry(
66a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        main_frame, same_document_loads, different_document_loads);
67a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
68a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (same_document_loads.empty() && different_document_loads.empty()) {
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // If we don't have any frames to navigate at this point, either
715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // (1) there is no previous history entry to compare against, or
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // (2) we were unable to match any frames by name. In the first case,
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // doing a different document navigation to the root item is the only valid
745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // thing to do. In the second case, we should have been able to find a
755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // frame to navigate based on names if this were a same document
765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // navigation, so we can safely assume this is the different document case.
775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    different_document_loads.push_back(
78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        std::make_pair(main_frame, provisional_entry_->root()));
79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
80a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
81a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  for (size_t i = 0; i < same_document_loads.size(); ++i) {
82a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    WebFrame* frame = same_document_loads[i].first;
83a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (!RenderFrameImpl::FromWebFrame(frame))
84a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      continue;
85a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    frame->loadHistoryItem(same_document_loads[i].second,
86a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                           blink::WebHistorySameDocumentLoad,
87a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                           cache_policy);
88a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
89a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  for (size_t i = 0; i < different_document_loads.size(); ++i) {
90a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    WebFrame* frame = different_document_loads[i].first;
91a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (!RenderFrameImpl::FromWebFrame(frame))
92a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      continue;
93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    frame->loadHistoryItem(different_document_loads[i].second,
94a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                           blink::WebHistoryDifferentDocumentLoad,
95a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                           cache_policy);
96a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
97a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
98a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
99a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HistoryController::RecursiveGoToEntry(
100a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    WebFrame* frame,
101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    HistoryFrameLoadVector& same_document_loads,
102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    HistoryFrameLoadVector& different_document_loads) {
103a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(provisional_entry_);
104a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(current_entry_);
105a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  RenderFrameImpl* render_frame = RenderFrameImpl::FromWebFrame(frame);
106a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const WebHistoryItem& new_item =
107a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      provisional_entry_->GetItemForFrame(render_frame);
108a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const WebHistoryItem& old_item =
109a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      current_entry_->GetItemForFrame(render_frame);
110a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (new_item.isNull())
111a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return;
112a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
113a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (old_item.isNull() ||
114a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      new_item.itemSequenceNumber() != old_item.itemSequenceNumber()) {
115a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (!old_item.isNull() &&
116a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        new_item.documentSequenceNumber() == old_item.documentSequenceNumber())
117a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      same_document_loads.push_back(std::make_pair(frame, new_item));
118a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    else
119a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      different_document_loads.push_back(std::make_pair(frame, new_item));
120a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return;
121a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
122a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  for (WebFrame* child = frame->firstChild(); child;
124a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch       child = child->nextSibling()) {
125a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RecursiveGoToEntry(child, same_document_loads, different_document_loads);
126a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
127a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
128a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
129a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HistoryController::UpdateForInitialLoadInChildFrame(
130a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RenderFrameImpl* frame,
131a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const WebHistoryItem& item) {
132a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK_NE(frame->GetWebFrame()->top(), frame->GetWebFrame());
133a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!current_entry_)
134a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return;
1350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (HistoryEntry::HistoryNode* existing_node =
1360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          current_entry_->GetHistoryNodeForFrame(frame)) {
137a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    existing_node->set_item(item);
138a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return;
139a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
140a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  RenderFrameImpl* parent =
141a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      RenderFrameImpl::FromWebFrame(frame->GetWebFrame()->parent());
1420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (HistoryEntry::HistoryNode* parent_history_node =
143a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          current_entry_->GetHistoryNodeForFrame(parent)) {
144a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    parent_history_node->AddChild(item, frame->GetRoutingID());
145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
147a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
148a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HistoryController::UpdateForCommit(RenderFrameImpl* frame,
149a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                        const WebHistoryItem& item,
150a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                        WebHistoryCommitType commit_type,
151a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                        bool navigation_within_page) {
152a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (commit_type == blink::WebBackForwardCommit) {
153a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (!provisional_entry_)
154a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      return;
155a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    current_entry_.reset(provisional_entry_.release());
156a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  } else if (commit_type == blink::WebStandardCommit) {
157a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    CreateNewBackForwardItem(frame, item, navigation_within_page);
158a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  } else if (commit_type == blink::WebInitialCommitInChildFrame) {
159a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    UpdateForInitialLoadInChildFrame(frame, item);
160a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
161a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
162a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuHistoryEntry* HistoryController::GetCurrentEntry() {
1645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return current_entry_.get();
165a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
166a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
167a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochWebHistoryItem HistoryController::GetItemForNewChildFrame(
168a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RenderFrameImpl* frame) const {
169a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!current_entry_)
170a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return WebHistoryItem();
171a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return current_entry_->GetItemForFrame(frame);
172a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
173a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
174a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HistoryController::RemoveChildrenForRedirect(RenderFrameImpl* frame) {
175a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!provisional_entry_)
176a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return;
1770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (HistoryEntry::HistoryNode* node =
1780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          provisional_entry_->GetHistoryNodeForFrame(frame))
179a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    node->RemoveChildren();
180a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
181a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
182a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid HistoryController::CreateNewBackForwardItem(
183a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    RenderFrameImpl* target_frame,
184a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const WebHistoryItem& new_item,
185a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    bool clone_children_of_target) {
186a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!current_entry_) {
187a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    current_entry_.reset(
188a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        new HistoryEntry(new_item, target_frame->GetRoutingID()));
189a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  } else {
190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    current_entry_.reset(current_entry_->CloneAndReplace(
191a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        new_item, clone_children_of_target, target_frame, render_view_));
192a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
193a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
194a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
195a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}  // namespace content
196