OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/tab_contents/navigation_controller_impl.h" | 5 #include "content/browser/tab_contents/navigation_controller_impl.h" |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/string_number_conversions.h" // Temporary | 9 #include "base/string_number_conversions.h" // Temporary |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 #include "content/public/browser/user_metrics.h" | 26 #include "content/public/browser/user_metrics.h" |
27 #include "content/public/browser/web_contents_delegate.h" | 27 #include "content/public/browser/web_contents_delegate.h" |
28 #include "content/public/common/content_constants.h" | 28 #include "content/public/common/content_constants.h" |
29 #include "net/base/escape.h" | 29 #include "net/base/escape.h" |
30 #include "net/base/mime_util.h" | 30 #include "net/base/mime_util.h" |
31 #include "net/base/net_util.h" | 31 #include "net/base/net_util.h" |
32 #include "webkit/glue/webkit_glue.h" | 32 #include "webkit/glue/webkit_glue.h" |
33 | 33 |
34 using content::BrowserContext; | 34 using content::BrowserContext; |
35 using content::GlobalRequestID; | 35 using content::GlobalRequestID; |
| 36 using content::NavigationController; |
36 using content::NavigationEntry; | 37 using content::NavigationEntry; |
37 using content::NavigationEntryImpl; | 38 using content::NavigationEntryImpl; |
38 using content::UserMetricsAction; | 39 using content::UserMetricsAction; |
39 using content::WebContents; | 40 using content::WebContents; |
40 | 41 |
41 namespace { | 42 namespace { |
42 | 43 |
43 const int kInvalidateAll = 0xFFFFFFFF; | 44 const int kInvalidateAll = 0xFFFFFFFF; |
44 | 45 |
45 // Invoked when entries have been pruned, or removed. For example, if the | 46 // Invoked when entries have been pruned, or removed. For example, if the |
46 // current entries are [google, digg, yahoo], with the current entry google, | 47 // current entries are [google, digg, yahoo], with the current entry google, |
47 // and the user types in cnet, then digg and yahoo are pruned. | 48 // and the user types in cnet, then digg and yahoo are pruned. |
48 void NotifyPrunedEntries(NavigationControllerImpl* nav_controller, | 49 void NotifyPrunedEntries(NavigationControllerImpl* nav_controller, |
49 bool from_front, | 50 bool from_front, |
50 int count) { | 51 int count) { |
51 content::PrunedDetails details; | 52 content::PrunedDetails details; |
52 details.from_front = from_front; | 53 details.from_front = from_front; |
53 details.count = count; | 54 details.count = count; |
54 content::NotificationService::current()->Notify( | 55 content::NotificationService::current()->Notify( |
55 content::NOTIFICATION_NAV_LIST_PRUNED, | 56 content::NOTIFICATION_NAV_LIST_PRUNED, |
56 content::Source<content::NavigationController>(nav_controller), | 57 content::Source<NavigationController>(nav_controller), |
57 content::Details<content::PrunedDetails>(&details)); | 58 content::Details<content::PrunedDetails>(&details)); |
58 } | 59 } |
59 | 60 |
60 // Ensure the given NavigationEntry has a valid state, so that WebKit does not | 61 // Ensure the given NavigationEntry has a valid state, so that WebKit does not |
61 // get confused if we navigate back to it. | 62 // get confused if we navigate back to it. |
62 // | 63 // |
63 // An empty state is treated as a new navigation by WebKit, which would mean | 64 // An empty state is treated as a new navigation by WebKit, which would mean |
64 // losing the navigation entries and generating a new navigation entry after | 65 // losing the navigation entries and generating a new navigation entry after |
65 // this one. We don't want that. To avoid this we create a valid state which | 66 // this one. We don't want that. To avoid this we create a valid state which |
66 // WebKit will not treat as a new navigation. | 67 // WebKit will not treat as a new navigation. |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 session_storage_namespace_ = new SessionStorageNamespace( | 182 session_storage_namespace_ = new SessionStorageNamespace( |
182 browser_context_->GetWebKitContext()); | 183 browser_context_->GetWebKitContext()); |
183 } | 184 } |
184 } | 185 } |
185 | 186 |
186 NavigationControllerImpl::~NavigationControllerImpl() { | 187 NavigationControllerImpl::~NavigationControllerImpl() { |
187 DiscardNonCommittedEntriesInternal(); | 188 DiscardNonCommittedEntriesInternal(); |
188 | 189 |
189 content::NotificationService::current()->Notify( | 190 content::NotificationService::current()->Notify( |
190 content::NOTIFICATION_TAB_CLOSED, | 191 content::NOTIFICATION_TAB_CLOSED, |
191 content::Source<content::NavigationController>(this), | 192 content::Source<NavigationController>(this), |
192 content::NotificationService::NoDetails()); | 193 content::NotificationService::NoDetails()); |
193 } | 194 } |
194 | 195 |
195 WebContents* NavigationControllerImpl::GetWebContents() const { | 196 WebContents* NavigationControllerImpl::GetWebContents() const { |
196 return tab_contents_; | 197 return tab_contents_; |
197 } | 198 } |
198 | 199 |
199 BrowserContext* NavigationControllerImpl::GetBrowserContext() const { | 200 BrowserContext* NavigationControllerImpl::GetBrowserContext() const { |
200 return browser_context_; | 201 return browser_context_; |
201 } | 202 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 return; | 248 return; |
248 } | 249 } |
249 | 250 |
250 if (g_check_for_repost && check_for_repost && | 251 if (g_check_for_repost && check_for_repost && |
251 GetEntryAtIndex(current_index)->GetHasPostData()) { | 252 GetEntryAtIndex(current_index)->GetHasPostData()) { |
252 // The user is asking to reload a page with POST data. Prompt to make sure | 253 // The user is asking to reload a page with POST data. Prompt to make sure |
253 // they really want to do this. If they do, the dialog will call us back | 254 // they really want to do this. If they do, the dialog will call us back |
254 // with check_for_repost = false. | 255 // with check_for_repost = false. |
255 content::NotificationService::current()->Notify( | 256 content::NotificationService::current()->Notify( |
256 content::NOTIFICATION_REPOST_WARNING_SHOWN, | 257 content::NOTIFICATION_REPOST_WARNING_SHOWN, |
257 content::Source<content::NavigationController>(this), | 258 content::Source<NavigationController>(this), |
258 content::NotificationService::NoDetails()); | 259 content::NotificationService::NoDetails()); |
259 | 260 |
260 pending_reload_ = reload_type; | 261 pending_reload_ = reload_type; |
261 tab_contents_->Activate(); | 262 tab_contents_->Activate(); |
262 tab_contents_->GetDelegate()->ShowRepostFormWarningDialog(tab_contents_); | 263 tab_contents_->GetDelegate()->ShowRepostFormWarningDialog(tab_contents_); |
263 } else { | 264 } else { |
264 DiscardNonCommittedEntriesInternal(); | 265 DiscardNonCommittedEntriesInternal(); |
265 | 266 |
266 pending_entry_index_ = current_index; | 267 pending_entry_index_ = current_index; |
267 entries_[pending_entry_index_]->SetTransitionType( | 268 entries_[pending_entry_index_]->SetTransitionType( |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 return; | 309 return; |
309 } | 310 } |
310 | 311 |
311 // When navigating to a new page, we don't know for sure if we will actually | 312 // When navigating to a new page, we don't know for sure if we will actually |
312 // end up leaving the current page. The new page load could for example | 313 // end up leaving the current page. The new page load could for example |
313 // result in a download or a 'no content' response (e.g., a mailto: URL). | 314 // result in a download or a 'no content' response (e.g., a mailto: URL). |
314 DiscardNonCommittedEntriesInternal(); | 315 DiscardNonCommittedEntriesInternal(); |
315 pending_entry_ = entry; | 316 pending_entry_ = entry; |
316 content::NotificationService::current()->Notify( | 317 content::NotificationService::current()->Notify( |
317 content::NOTIFICATION_NAV_ENTRY_PENDING, | 318 content::NOTIFICATION_NAV_ENTRY_PENDING, |
318 content::Source<content::NavigationController>(this), | 319 content::Source<NavigationController>(this), |
319 content::Details<NavigationEntry>(entry)); | 320 content::Details<NavigationEntry>(entry)); |
320 NavigateToPendingEntry(NO_RELOAD); | 321 NavigateToPendingEntry(NO_RELOAD); |
321 } | 322 } |
322 | 323 |
323 NavigationEntry* NavigationControllerImpl::GetActiveEntry() const { | 324 NavigationEntry* NavigationControllerImpl::GetActiveEntry() const { |
324 if (transient_entry_index_ != -1) | 325 if (transient_entry_index_ != -1) |
325 return entries_[transient_entry_index_].get(); | 326 return entries_[transient_entry_index_].get(); |
326 if (pending_entry_) | 327 if (pending_entry_) |
327 return pending_entry_; | 328 return pending_entry_; |
328 return GetLastCommittedEntry(); | 329 return GetLastCommittedEntry(); |
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
966 } | 967 } |
967 | 968 |
968 bool NavigationControllerImpl::IsURLInPageNavigation(const GURL& url) const { | 969 bool NavigationControllerImpl::IsURLInPageNavigation(const GURL& url) const { |
969 NavigationEntry* last_committed = GetLastCommittedEntry(); | 970 NavigationEntry* last_committed = GetLastCommittedEntry(); |
970 if (!last_committed) | 971 if (!last_committed) |
971 return false; | 972 return false; |
972 return AreURLsInPageNavigation(last_committed->GetURL(), url); | 973 return AreURLsInPageNavigation(last_committed->GetURL(), url); |
973 } | 974 } |
974 | 975 |
975 void NavigationControllerImpl::CopyStateFrom( | 976 void NavigationControllerImpl::CopyStateFrom( |
976 const content::NavigationController& temp) { | 977 const NavigationController& temp) { |
977 const NavigationControllerImpl& source = | 978 const NavigationControllerImpl& source = |
978 static_cast<const NavigationControllerImpl&>(temp); | 979 static_cast<const NavigationControllerImpl&>(temp); |
979 // Verify that we look new. | 980 // Verify that we look new. |
980 DCHECK(GetEntryCount() == 0 && !GetPendingEntry()); | 981 DCHECK(GetEntryCount() == 0 && !GetPendingEntry()); |
981 | 982 |
982 if (source.GetEntryCount() == 0) | 983 if (source.GetEntryCount() == 0) |
983 return; // Nothing new to do. | 984 return; // Nothing new to do. |
984 | 985 |
985 needs_reload_ = true; | 986 needs_reload_ = true; |
986 InsertEntriesFrom(source, source.GetEntryCount()); | 987 InsertEntriesFrom(source, source.GetEntryCount()); |
987 | 988 |
988 session_storage_namespace_ = source.session_storage_namespace_->Clone(); | 989 session_storage_namespace_ = source.session_storage_namespace_->Clone(); |
989 | 990 |
990 FinishRestore(source.last_committed_entry_index_, false); | 991 FinishRestore(source.last_committed_entry_index_, false); |
991 } | 992 } |
992 | 993 |
993 void NavigationControllerImpl::CopyStateFromAndPrune( | 994 void NavigationControllerImpl::CopyStateFromAndPrune( |
994 content::NavigationController* temp) { | 995 NavigationController* temp) { |
995 NavigationControllerImpl* source = | 996 NavigationControllerImpl* source = |
996 static_cast<NavigationControllerImpl*>(temp); | 997 static_cast<NavigationControllerImpl*>(temp); |
997 // The SiteInstance and page_id of the last committed entry needs to be | 998 // The SiteInstance and page_id of the last committed entry needs to be |
998 // remembered at this point, in case there is only one committed entry | 999 // remembered at this point, in case there is only one committed entry |
999 // and it is pruned. | 1000 // and it is pruned. |
1000 NavigationEntryImpl* last_committed = | 1001 NavigationEntryImpl* last_committed = |
1001 NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry()); | 1002 NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry()); |
1002 SiteInstance* site_instance = | 1003 SiteInstance* site_instance = |
1003 last_committed ? last_committed->site_instance() : NULL; | 1004 last_committed ? last_committed->site_instance() : NULL; |
1004 int32 minimum_page_id = last_committed ? last_committed->GetPageID() : -1; | 1005 int32 minimum_page_id = last_committed ? last_committed->GetPageID() : -1; |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1242 // when it wants to draw. See http://crbug.com/11157 | 1243 // when it wants to draw. See http://crbug.com/11157 |
1243 ssl_manager_.DidCommitProvisionalLoad(notification_details); | 1244 ssl_manager_.DidCommitProvisionalLoad(notification_details); |
1244 | 1245 |
1245 // TODO(pkasting): http://b/1113079 Probably these explicit notification paths | 1246 // TODO(pkasting): http://b/1113079 Probably these explicit notification paths |
1246 // should be removed, and interested parties should just listen for the | 1247 // should be removed, and interested parties should just listen for the |
1247 // notification below instead. | 1248 // notification below instead. |
1248 tab_contents_->NotifyNavigationStateChanged(kInvalidateAll); | 1249 tab_contents_->NotifyNavigationStateChanged(kInvalidateAll); |
1249 | 1250 |
1250 content::NotificationService::current()->Notify( | 1251 content::NotificationService::current()->Notify( |
1251 content::NOTIFICATION_NAV_ENTRY_COMMITTED, | 1252 content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
1252 content::Source<content::NavigationController>(this), | 1253 content::Source<NavigationController>(this), |
1253 notification_details); | 1254 notification_details); |
1254 } | 1255 } |
1255 | 1256 |
1256 // static | 1257 // static |
1257 size_t NavigationControllerImpl::max_entry_count() { | 1258 size_t NavigationControllerImpl::max_entry_count() { |
1258 if (max_entry_count_for_testing_ != kMaxEntryCountForTestingNotSet) | 1259 if (max_entry_count_for_testing_ != kMaxEntryCountForTestingNotSet) |
1259 return max_entry_count_for_testing_; | 1260 return max_entry_count_for_testing_; |
1260 return content::kMaxSessionHistoryEntries; | 1261 return content::kMaxSessionHistoryEntries; |
1261 } | 1262 } |
1262 | 1263 |
(...skipping 13 matching lines...) Expand all Loading... |
1276 NavigateToPendingEntry(NO_RELOAD); | 1277 NavigateToPendingEntry(NO_RELOAD); |
1277 } | 1278 } |
1278 | 1279 |
1279 void NavigationControllerImpl::NotifyEntryChanged(const NavigationEntry* entry, | 1280 void NavigationControllerImpl::NotifyEntryChanged(const NavigationEntry* entry, |
1280 int index) { | 1281 int index) { |
1281 content::EntryChangedDetails det; | 1282 content::EntryChangedDetails det; |
1282 det.changed_entry = entry; | 1283 det.changed_entry = entry; |
1283 det.index = index; | 1284 det.index = index; |
1284 content::NotificationService::current()->Notify( | 1285 content::NotificationService::current()->Notify( |
1285 content::NOTIFICATION_NAV_ENTRY_CHANGED, | 1286 content::NOTIFICATION_NAV_ENTRY_CHANGED, |
1286 content::Source<content::NavigationController>(this), | 1287 content::Source<NavigationController>(this), |
1287 content::Details<content::EntryChangedDetails>(&det)); | 1288 content::Details<content::EntryChangedDetails>(&det)); |
1288 } | 1289 } |
1289 | 1290 |
1290 void NavigationControllerImpl::FinishRestore(int selected_index, | 1291 void NavigationControllerImpl::FinishRestore(int selected_index, |
1291 bool from_last_session) { | 1292 bool from_last_session) { |
1292 DCHECK(selected_index >= 0 && selected_index < GetEntryCount()); | 1293 DCHECK(selected_index >= 0 && selected_index < GetEntryCount()); |
1293 ConfigureEntriesForRestore(&entries_, from_last_session); | 1294 ConfigureEntriesForRestore(&entries_, from_last_session); |
1294 | 1295 |
1295 SetMaxRestoredPageID(static_cast<int32>(GetEntryCount())); | 1296 SetMaxRestoredPageID(static_cast<int32>(GetEntryCount())); |
1296 | 1297 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1339 for (int i = 0; i < max_index; i++) { | 1340 for (int i = 0; i < max_index; i++) { |
1340 // When cloning a tab, copy all entries except interstitial pages | 1341 // When cloning a tab, copy all entries except interstitial pages |
1341 if (source.entries_[i].get()->GetPageType() != | 1342 if (source.entries_[i].get()->GetPageType() != |
1342 content::PAGE_TYPE_INTERSTITIAL) { | 1343 content::PAGE_TYPE_INTERSTITIAL) { |
1343 entries_.insert(entries_.begin() + insert_index++, | 1344 entries_.insert(entries_.begin() + insert_index++, |
1344 linked_ptr<NavigationEntryImpl>( | 1345 linked_ptr<NavigationEntryImpl>( |
1345 new NavigationEntryImpl(*source.entries_[i]))); | 1346 new NavigationEntryImpl(*source.entries_[i]))); |
1346 } | 1347 } |
1347 } | 1348 } |
1348 } | 1349 } |
OLD | NEW |