Index: ios/web/navigation/navigation_manager_impl.mm |
diff --git a/ios/web/navigation/navigation_manager_impl.mm b/ios/web/navigation/navigation_manager_impl.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f445104db14eeeb0077c7a0b6abba6f3e36d2dbe |
--- /dev/null |
+++ b/ios/web/navigation/navigation_manager_impl.mm |
@@ -0,0 +1,251 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "ios/web/navigation/navigation_manager_impl.h" |
+ |
+#include "base/logging.h" |
+#import "ios/web/navigation/crw_session_controller+private_constructors.h" |
+#import "ios/web/navigation/crw_session_controller.h" |
+#import "ios/web/navigation/crw_session_entry.h" |
+#include "ios/web/navigation/navigation_item_impl.h" |
+#include "ios/web/navigation/navigation_manager_delegate.h" |
+#import "ios/web/navigation/navigation_manager_facade_delegate.h" |
+#include "ios/web/public/load_committed_details.h" |
+#include "ios/web/public/navigation_item.h" |
+#include "ios/web/public/web_state/web_state.h" |
+#include "ui/base/page_transition_types.h" |
+ |
+namespace { |
+ |
+// Checks whether or not two URL are an in-page navigation (differing only |
+// in the fragment). |
+bool AreURLsInPageNavigation(const GURL& existing_url, const GURL& new_url) { |
+ if (existing_url == new_url || !new_url.has_ref()) |
+ return false; |
+ |
+ url::Replacements<char> replacements; |
+ replacements.ClearRef(); |
+ return existing_url.ReplaceComponents(replacements) == |
+ new_url.ReplaceComponents(replacements); |
+} |
+ |
+} // anonymous namespace |
+ |
+namespace web { |
+ |
+NavigationManagerImpl::NavigationManagerImpl( |
+ NavigationManagerDelegate* delegate, |
+ BrowserState* browser_state) |
+ : delegate_(delegate), |
+ browser_state_(browser_state), |
+ facade_delegate_(nullptr) { |
+ DCHECK(browser_state_); |
+} |
+ |
+NavigationManagerImpl::~NavigationManagerImpl() { |
+ // The facade layer should be deleted before this object. |
+ DCHECK(!facade_delegate_); |
+ |
+ [session_controller_ setNavigationManager:nullptr]; |
+} |
+ |
+CRWSessionController* NavigationManagerImpl::GetSessionController() { |
+ return session_controller_; |
+} |
+ |
+void NavigationManagerImpl::SetSessionController( |
+ CRWSessionController* session_controller) { |
+ session_controller_.reset([session_controller retain]); |
+ [session_controller_ setNavigationManager:this]; |
+} |
+ |
+void NavigationManagerImpl::InitializeSession(NSString* window_name, |
+ NSString* opener_id, |
+ BOOL opened_by_dom, |
+ int opener_navigation_index) { |
+ SetSessionController([[[CRWSessionController alloc] |
+ initWithWindowName:window_name |
+ openerId:opener_id |
+ openedByDOM:opened_by_dom |
+ openerNavigationIndex:opener_navigation_index |
+ browserState:browser_state_] autorelease]); |
+} |
+ |
+void NavigationManagerImpl::ReplaceSessionHistory( |
+ ScopedVector<web::NavigationItem> items, |
+ int current_index) { |
+ SetSessionController([[[CRWSessionController alloc] |
+ initWithNavigationItems:items.Pass() |
+ currentIndex:current_index |
+ browserState:browser_state_] autorelease]); |
+} |
+ |
+void NavigationManagerImpl::SetFacadeDelegate( |
+ NavigationManagerFacadeDelegate* facade_delegate) { |
+ facade_delegate_ = facade_delegate; |
+} |
+ |
+NavigationManagerFacadeDelegate* NavigationManagerImpl::GetFacadeDelegate() |
+ const { |
+ return facade_delegate_; |
+} |
+ |
+ |
+void NavigationManagerImpl::OnNavigationItemChanged() { |
+ if (facade_delegate_) |
+ facade_delegate_->OnNavigationItemChanged(); |
+} |
+ |
+void NavigationManagerImpl::OnNavigationItemCommitted() { |
+ LoadCommittedDetails details; |
+ details.item = GetLastCommittedItem(); |
+ DCHECK(details.item); |
+ details.previous_item_index = [session_controller_ previousNavigationIndex]; |
+ if (details.previous_item_index >= 0) { |
+ DCHECK([session_controller_ previousEntry]); |
+ details.previous_url = |
+ [session_controller_ previousEntry].navigationItem->GetURL(); |
+ details.is_in_page = |
+ AreURLsInPageNavigation(details.previous_url, details.item->GetURL()); |
+ } else { |
+ details.previous_url = GURL(); |
+ details.is_in_page = NO; |
+ } |
+ |
+ delegate_->OnNavigationItemCommitted(details); |
+ |
+ if (facade_delegate_) { |
+ facade_delegate_->OnNavigationItemCommitted(details.previous_item_index, |
+ details.is_in_page); |
+ } |
+} |
+ |
+NavigationItem* NavigationManagerImpl::GetVisibleItem() const { |
+ CRWSessionEntry* entry = [session_controller_ visibleEntry]; |
+ return [entry navigationItem]; |
+} |
+ |
+NavigationItem* NavigationManagerImpl::GetPendingItem() const { |
+ return [[session_controller_ pendingEntry] navigationItem]; |
+} |
+ |
+NavigationItem* NavigationManagerImpl::GetTransientItem() const { |
+ return [[session_controller_ transientEntry] navigationItem]; |
+} |
+ |
+NavigationItem* NavigationManagerImpl::GetLastCommittedItem() const { |
+ CRWSessionEntry* entry = [session_controller_ lastCommittedEntry]; |
+ return [entry navigationItem]; |
+} |
+ |
+NavigationItem* NavigationManagerImpl::GetItemAtIndex(size_t index) const { |
+ NSArray* entries = [session_controller_ entries]; |
+ return index < entries.count ? [entries[index] navigationItem] : nullptr; |
+} |
+ |
+int NavigationManagerImpl::GetCurrentEntryIndex() const { |
+ return [session_controller_ currentNavigationIndex]; |
+} |
+ |
+int NavigationManagerImpl::GetLastCommittedEntryIndex() const { |
+ if (![[session_controller_ entries] count]) |
+ return -1; |
+ return [session_controller_ currentNavigationIndex]; |
+} |
+ |
+int NavigationManagerImpl::GetEntryCount() const { |
+ return [[session_controller_ entries] count]; |
+} |
+ |
+bool NavigationManagerImpl::RemoveEntryAtIndex(int index) { |
+ if (index == GetLastCommittedEntryIndex() || |
+ index == GetPendingEntryIndex()) |
+ return false; |
+ |
+ NSUInteger idx = static_cast<NSUInteger>(index); |
+ NSArray* entries = [session_controller_ entries]; |
+ if (idx >= entries.count) |
+ return false; |
+ |
+ [session_controller_ removeEntryAtIndex:index]; |
+ return true; |
+} |
+ |
+void NavigationManagerImpl::DiscardNonCommittedEntries() { |
+ [session_controller_ discardNonCommittedEntries]; |
+} |
+ |
+NavigationItem* NavigationManagerImpl::GetLastUserItem() const { |
+ CRWSessionEntry* entry = [session_controller_ lastUserEntry]; |
+ return [entry navigationItem]; |
+} |
+ |
+NavigationItem* NavigationManagerImpl::GetPreviousItem() const { |
+ CRWSessionEntry* entry = [session_controller_ previousEntry]; |
+ return [entry navigationItem]; |
+} |
+ |
+int NavigationManagerImpl::GetPendingEntryIndex() const { |
+ if ([session_controller_ hasPendingEntry]) |
+ return GetCurrentEntryIndex(); |
+ return -1; |
+} |
+ |
+void NavigationManagerImpl::LoadURL(const GURL& url, |
+ const web::Referrer& referrer, |
+ ui::PageTransition type) { |
+ WebState::OpenURLParams params(url, referrer, CURRENT_TAB, type, NO); |
+ delegate_->GetWebState()->OpenURL(params); |
+} |
+ |
+bool NavigationManagerImpl::CanGoBack() const { |
+ return [session_controller_ canGoBack]; |
+} |
+ |
+bool NavigationManagerImpl::CanGoForward() const { |
+ return [session_controller_ canGoForward]; |
+} |
+ |
+void NavigationManagerImpl::GoBack() { |
+ if (CanGoBack()) { |
+ [session_controller_ goBack]; |
+ // Signal the delegate to load the old page. |
+ delegate_->NavigateToPendingEntry(); |
+ } |
+} |
+ |
+void NavigationManagerImpl::GoForward() { |
+ if (CanGoForward()) { |
+ [session_controller_ goForward]; |
+ // Signal the delegate to load the new page. |
+ delegate_->NavigateToPendingEntry(); |
+ } |
+} |
+ |
+std::vector<NavigationItem*> NavigationManagerImpl::GetItems() { |
+ std::vector<NavigationItem*> items; |
+ size_t i = 0; |
+ items.resize([session_controller_ entries].count); |
+ for (CRWSessionEntry* entry in [session_controller_ entries]) { |
+ items[i++] = entry.navigationItem; |
+ } |
+ return items; |
+} |
+ |
+BrowserState* NavigationManagerImpl::GetBrowserState() const { |
+ return browser_state_; |
+} |
+ |
+WebState* NavigationManagerImpl::GetWebState() const { |
+ return delegate_->GetWebState(); |
+} |
+ |
+void NavigationManagerImpl::CopyState( |
+ NavigationManagerImpl* navigation_manager) { |
+ SetSessionController( |
+ [[navigation_manager->GetSessionController() copy] autorelease]); |
+} |
+ |
+} // namespace web |
+ |