Add ICU message format support
[chromium-blink-merge.git] / ios / web / navigation / navigation_manager_impl.mm
blobb8ced311320a937fd4ef1d27bd5e007ff5cf8624
1 // Copyright 2013 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.
5 #include "ios/web/navigation/navigation_manager_impl.h"
7 #include "base/logging.h"
8 #import "ios/web/navigation/crw_session_controller+private_constructors.h"
9 #import "ios/web/navigation/crw_session_controller.h"
10 #import "ios/web/navigation/crw_session_entry.h"
11 #include "ios/web/navigation/navigation_item_impl.h"
12 #include "ios/web/navigation/navigation_manager_delegate.h"
13 #import "ios/web/navigation/navigation_manager_facade_delegate.h"
14 #include "ios/web/public/load_committed_details.h"
15 #include "ios/web/public/navigation_item.h"
16 #include "ios/web/public/web_state/web_state.h"
17 #include "ui/base/page_transition_types.h"
19 namespace {
21 // Checks whether or not two URL are an in-page navigation (differing only
22 // in the fragment).
23 bool AreURLsInPageNavigation(const GURL& existing_url, const GURL& new_url) {
24   if (existing_url == new_url || !new_url.has_ref())
25     return false;
27   url::Replacements<char> replacements;
28   replacements.ClearRef();
29   return existing_url.ReplaceComponents(replacements) ==
30       new_url.ReplaceComponents(replacements);
33 }  // anonymous namespace
35 namespace web {
37 NavigationManagerImpl::NavigationManagerImpl(
38     NavigationManagerDelegate* delegate,
39     BrowserState* browser_state)
40     : delegate_(delegate),
41       browser_state_(browser_state),
42       facade_delegate_(nullptr) {
43   DCHECK(browser_state_);
46 NavigationManagerImpl::~NavigationManagerImpl() {
47   // The facade layer should be deleted before this object.
48   DCHECK(!facade_delegate_);
50   [session_controller_ setNavigationManager:nullptr];
53 CRWSessionController* NavigationManagerImpl::GetSessionController() {
54   return session_controller_;
57 void NavigationManagerImpl::SetSessionController(
58     CRWSessionController* session_controller) {
59   session_controller_.reset([session_controller retain]);
60   [session_controller_ setNavigationManager:this];
63 void NavigationManagerImpl::InitializeSession(NSString* window_name,
64                                               NSString* opener_id,
65                                               BOOL opened_by_dom,
66                                               int opener_navigation_index) {
67   SetSessionController([[[CRWSessionController alloc]
68          initWithWindowName:window_name
69                    openerId:opener_id
70                 openedByDOM:opened_by_dom
71       openerNavigationIndex:opener_navigation_index
72                browserState:browser_state_] autorelease]);
75 void NavigationManagerImpl::ReplaceSessionHistory(
76     ScopedVector<web::NavigationItem> items,
77     int current_index) {
78   SetSessionController([[[CRWSessionController alloc]
79       initWithNavigationItems:items.Pass()
80                  currentIndex:current_index
81                  browserState:browser_state_] autorelease]);
84 void NavigationManagerImpl::SetFacadeDelegate(
85     NavigationManagerFacadeDelegate* facade_delegate) {
86   facade_delegate_ = facade_delegate;
89 NavigationManagerFacadeDelegate* NavigationManagerImpl::GetFacadeDelegate()
90     const {
91   return facade_delegate_;
95 void NavigationManagerImpl::OnNavigationItemChanged() {
96   if (facade_delegate_)
97     facade_delegate_->OnNavigationItemChanged();
100 void NavigationManagerImpl::OnNavigationItemCommitted() {
101   LoadCommittedDetails details;
102   details.item = GetLastCommittedItem();
103   DCHECK(details.item);
104   details.previous_item_index = [session_controller_ previousNavigationIndex];
105   if (details.previous_item_index >= 0) {
106     DCHECK([session_controller_ previousEntry]);
107     details.previous_url =
108         [session_controller_ previousEntry].navigationItem->GetURL();
109     details.is_in_page =
110         AreURLsInPageNavigation(details.previous_url, details.item->GetURL());
111   } else {
112     details.previous_url = GURL();
113     details.is_in_page = NO;
114   }
116   delegate_->OnNavigationItemCommitted(details);
118   if (facade_delegate_) {
119     facade_delegate_->OnNavigationItemCommitted(details.previous_item_index,
120                                                 details.is_in_page);
121   }
124 NavigationItem* NavigationManagerImpl::GetVisibleItem() const {
125   CRWSessionEntry* entry = [session_controller_ visibleEntry];
126   return [entry navigationItem];
129 NavigationItem* NavigationManagerImpl::GetPendingItem() const {
130   return [[session_controller_ pendingEntry] navigationItem];
133 NavigationItem* NavigationManagerImpl::GetTransientItem() const {
134   return [[session_controller_ transientEntry] navigationItem];
137 NavigationItem* NavigationManagerImpl::GetLastCommittedItem() const {
138   CRWSessionEntry* entry = [session_controller_ lastCommittedEntry];
139   return [entry navigationItem];
142 NavigationItem* NavigationManagerImpl::GetItemAtIndex(size_t index) const {
143   NSArray* entries =  [session_controller_ entries];
144   return index < entries.count ? [entries[index] navigationItem] : nullptr;
147 int NavigationManagerImpl::GetCurrentEntryIndex() const {
148   return [session_controller_ currentNavigationIndex];
151 int NavigationManagerImpl::GetLastCommittedEntryIndex() const {
152   if (![[session_controller_ entries] count])
153     return -1;
154   return [session_controller_ currentNavigationIndex];
157 int NavigationManagerImpl::GetEntryCount() const {
158   return [[session_controller_ entries] count];
161 bool NavigationManagerImpl::RemoveEntryAtIndex(int index) {
162   if (index == GetLastCommittedEntryIndex() ||
163       index == GetPendingEntryIndex())
164     return false;
166   NSUInteger idx = static_cast<NSUInteger>(index);
167   NSArray* entries = [session_controller_ entries];
168   if (idx >= entries.count)
169     return false;
171   [session_controller_ removeEntryAtIndex:index];
172   return true;
175 void NavigationManagerImpl::DiscardNonCommittedEntries() {
176   [session_controller_ discardNonCommittedEntries];
179 NavigationItem* NavigationManagerImpl::GetLastUserItem() const {
180   CRWSessionEntry* entry = [session_controller_ lastUserEntry];
181   return [entry navigationItem];
184 NavigationItem* NavigationManagerImpl::GetPreviousItem() const {
185   CRWSessionEntry* entry = [session_controller_ previousEntry];
186   return [entry navigationItem];
189 int NavigationManagerImpl::GetPendingEntryIndex() const {
190   if ([session_controller_ hasPendingEntry])
191     return GetCurrentEntryIndex();
192   return -1;
195 void NavigationManagerImpl::AddTransientURLRewriter(
196     BrowserURLRewriter::URLRewriter rewriter) {
197   DCHECK(rewriter);
198   if (!transient_url_rewriters_) {
199     transient_url_rewriters_.reset(
200         new std::vector<BrowserURLRewriter::URLRewriter>());
201   }
202   transient_url_rewriters_->push_back(rewriter);
205 scoped_ptr<std::vector<BrowserURLRewriter::URLRewriter>>
206 NavigationManagerImpl::GetTransientURLRewriters() {
207   return transient_url_rewriters_.Pass();
210 void NavigationManagerImpl::RemoveTransientURLRewriters() {
211   transient_url_rewriters_.reset();
214 void NavigationManagerImpl::LoadURL(const GURL& url,
215                                     const web::Referrer& referrer,
216                                     ui::PageTransition type) {
217   WebState::OpenURLParams params(url, referrer, CURRENT_TAB, type, NO);
218   delegate_->GetWebState()->OpenURL(params);
221 bool NavigationManagerImpl::CanGoBack() const {
222   return [session_controller_ canGoBack];
225 bool NavigationManagerImpl::CanGoForward() const {
226   return [session_controller_ canGoForward];
229 void NavigationManagerImpl::GoBack() {
230   if (CanGoBack()) {
231     [session_controller_ goBack];
232     // Signal the delegate to load the old page.
233     delegate_->NavigateToPendingEntry();
234   }
237 void NavigationManagerImpl::GoForward() {
238   if (CanGoForward()) {
239     [session_controller_ goForward];
240     // Signal the delegate to load the new page.
241     delegate_->NavigateToPendingEntry();
242   }
245 std::vector<NavigationItem*> NavigationManagerImpl::GetItems() {
246   std::vector<NavigationItem*> items;
247   size_t i = 0;
248   items.resize([session_controller_ entries].count);
249   for (CRWSessionEntry* entry in [session_controller_ entries]) {
250     items[i++] = entry.navigationItem;
251   }
252   return items;
255 BrowserState* NavigationManagerImpl::GetBrowserState() const {
256   return browser_state_;
259 WebState* NavigationManagerImpl::GetWebState() const {
260   return delegate_->GetWebState();
263 void NavigationManagerImpl::CopyState(
264     NavigationManagerImpl* navigation_manager) {
265   SetSessionController(
266       [[navigation_manager->GetSessionController() copy] autorelease]);
269 }  // namespace web