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