| 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.h" | 5 #include "content/browser/tab_contents/navigation_controller.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_util.h" | 9 #include "base/string_util.h" |
| 10 #include "base/time.h" | 10 #include "base/time.h" |
| 11 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
| 12 #include "content/browser/browser_context.h" | 12 #include "content/browser/browser_context.h" |
| 13 #include "content/browser/browser_url_handler.h" | 13 #include "content/browser/browser_url_handler.h" |
| 14 #include "content/browser/child_process_security_policy.h" | 14 #include "content/browser/child_process_security_policy.h" |
| 15 #include "content/browser/in_process_webkit/session_storage_namespace.h" | 15 #include "content/browser/in_process_webkit/session_storage_namespace.h" |
| 16 #include "content/browser/site_instance.h" | 16 #include "content/browser/site_instance.h" |
| 17 #include "content/browser/tab_contents/interstitial_page.h" | 17 #include "content/browser/tab_contents/interstitial_page.h" |
| 18 #include "content/browser/tab_contents/navigation_details.h" | 18 #include "content/browser/tab_contents/navigation_details.h" |
| 19 #include "content/browser/tab_contents/navigation_entry.h" | 19 #include "content/browser/tab_contents/navigation_entry.h" |
| 20 #include "content/browser/tab_contents/tab_contents.h" | 20 #include "content/browser/tab_contents/tab_contents.h" |
| 21 #include "content/browser/tab_contents/tab_contents_delegate.h" | 21 #include "content/browser/tab_contents/tab_contents_delegate.h" |
| 22 #include "content/browser/user_metrics.h" | 22 #include "content/browser/user_metrics.h" |
| 23 #include "content/common/content_constants.h" | 23 #include "content/common/content_constants.h" |
| 24 #include "content/common/notification_service.h" | 24 #include "content/public/browser/notification_service.h" |
| 25 #include "content/common/view_messages.h" | 25 #include "content/common/view_messages.h" |
| 26 #include "content/public/browser/notification_types.h" | 26 #include "content/public/browser/notification_types.h" |
| 27 #include "net/base/escape.h" | 27 #include "net/base/escape.h" |
| 28 #include "net/base/mime_util.h" | 28 #include "net/base/mime_util.h" |
| 29 #include "net/base/net_util.h" | 29 #include "net/base/net_util.h" |
| 30 #include "webkit/glue/webkit_glue.h" | 30 #include "webkit/glue/webkit_glue.h" |
| 31 | 31 |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 const int kInvalidateAll = 0xFFFFFFFF; | 34 const int kInvalidateAll = 0xFFFFFFFF; |
| 35 | 35 |
| 36 // Invoked when entries have been pruned, or removed. For example, if the | 36 // Invoked when entries have been pruned, or removed. For example, if the |
| 37 // current entries are [google, digg, yahoo], with the current entry google, | 37 // current entries are [google, digg, yahoo], with the current entry google, |
| 38 // and the user types in cnet, then digg and yahoo are pruned. | 38 // and the user types in cnet, then digg and yahoo are pruned. |
| 39 void NotifyPrunedEntries(NavigationController* nav_controller, | 39 void NotifyPrunedEntries(NavigationController* nav_controller, |
| 40 bool from_front, | 40 bool from_front, |
| 41 int count) { | 41 int count) { |
| 42 content::PrunedDetails details; | 42 content::PrunedDetails details; |
| 43 details.from_front = from_front; | 43 details.from_front = from_front; |
| 44 details.count = count; | 44 details.count = count; |
| 45 NotificationService::current()->Notify( | 45 content::NotificationService::current()->Notify( |
| 46 content::NOTIFICATION_NAV_LIST_PRUNED, | 46 content::NOTIFICATION_NAV_LIST_PRUNED, |
| 47 content::Source<NavigationController>(nav_controller), | 47 content::Source<NavigationController>(nav_controller), |
| 48 content::Details<content::PrunedDetails>(&details)); | 48 content::Details<content::PrunedDetails>(&details)); |
| 49 } | 49 } |
| 50 | 50 |
| 51 // Ensure the given NavigationEntry has a valid state, so that WebKit does not | 51 // Ensure the given NavigationEntry has a valid state, so that WebKit does not |
| 52 // get confused if we navigate back to it. | 52 // get confused if we navigate back to it. |
| 53 // | 53 // |
| 54 // An empty state is treated as a new navigation by WebKit, which would mean | 54 // An empty state is treated as a new navigation by WebKit, which would mean |
| 55 // losing the navigation entries and generating a new navigation entry after | 55 // losing the navigation entries and generating a new navigation entry after |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 DCHECK(browser_context_); | 126 DCHECK(browser_context_); |
| 127 if (!session_storage_namespace_) { | 127 if (!session_storage_namespace_) { |
| 128 session_storage_namespace_ = new SessionStorageNamespace( | 128 session_storage_namespace_ = new SessionStorageNamespace( |
| 129 browser_context_->GetWebKitContext()); | 129 browser_context_->GetWebKitContext()); |
| 130 } | 130 } |
| 131 } | 131 } |
| 132 | 132 |
| 133 NavigationController::~NavigationController() { | 133 NavigationController::~NavigationController() { |
| 134 DiscardNonCommittedEntriesInternal(); | 134 DiscardNonCommittedEntriesInternal(); |
| 135 | 135 |
| 136 NotificationService::current()->Notify( | 136 content::NotificationService::current()->Notify( |
| 137 content::NOTIFICATION_TAB_CLOSED, | 137 content::NOTIFICATION_TAB_CLOSED, |
| 138 content::Source<NavigationController>(this), | 138 content::Source<NavigationController>(this), |
| 139 NotificationService::NoDetails()); | 139 content::NotificationService::NoDetails()); |
| 140 } | 140 } |
| 141 | 141 |
| 142 void NavigationController::Restore( | 142 void NavigationController::Restore( |
| 143 int selected_navigation, | 143 int selected_navigation, |
| 144 bool from_last_session, | 144 bool from_last_session, |
| 145 std::vector<NavigationEntry*>* entries) { | 145 std::vector<NavigationEntry*>* entries) { |
| 146 // Verify that this controller is unused and that the input is valid. | 146 // Verify that this controller is unused and that the input is valid. |
| 147 DCHECK(entry_count() == 0 && !pending_entry()); | 147 DCHECK(entry_count() == 0 && !pending_entry()); |
| 148 DCHECK(selected_navigation >= 0 && | 148 DCHECK(selected_navigation >= 0 && |
| 149 selected_navigation < static_cast<int>(entries->size())); | 149 selected_navigation < static_cast<int>(entries->size())); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 176 // CanReload method. | 176 // CanReload method. |
| 177 if (current_index == -1) { | 177 if (current_index == -1) { |
| 178 return; | 178 return; |
| 179 } | 179 } |
| 180 | 180 |
| 181 if (check_for_repost_ && check_for_repost && | 181 if (check_for_repost_ && check_for_repost && |
| 182 GetEntryAtIndex(current_index)->has_post_data()) { | 182 GetEntryAtIndex(current_index)->has_post_data()) { |
| 183 // The user is asking to reload a page with POST data. Prompt to make sure | 183 // The user is asking to reload a page with POST data. Prompt to make sure |
| 184 // they really want to do this. If they do, the dialog will call us back | 184 // they really want to do this. If they do, the dialog will call us back |
| 185 // with check_for_repost = false. | 185 // with check_for_repost = false. |
| 186 NotificationService::current()->Notify( | 186 content::NotificationService::current()->Notify( |
| 187 content::NOTIFICATION_REPOST_WARNING_SHOWN, | 187 content::NOTIFICATION_REPOST_WARNING_SHOWN, |
| 188 content::Source<NavigationController>(this), | 188 content::Source<NavigationController>(this), |
| 189 NotificationService::NoDetails()); | 189 content::NotificationService::NoDetails()); |
| 190 | 190 |
| 191 pending_reload_ = reload_type; | 191 pending_reload_ = reload_type; |
| 192 tab_contents_->Activate(); | 192 tab_contents_->Activate(); |
| 193 tab_contents_->delegate()->ShowRepostFormWarningDialog(tab_contents_); | 193 tab_contents_->delegate()->ShowRepostFormWarningDialog(tab_contents_); |
| 194 } else { | 194 } else { |
| 195 DiscardNonCommittedEntriesInternal(); | 195 DiscardNonCommittedEntriesInternal(); |
| 196 | 196 |
| 197 pending_entry_index_ = current_index; | 197 pending_entry_index_ = current_index; |
| 198 entries_[pending_entry_index_]->set_transition_type( | 198 entries_[pending_entry_index_]->set_transition_type( |
| 199 content::PAGE_TRANSITION_RELOAD); | 199 content::PAGE_TRANSITION_RELOAD); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 << entry->url(); | 267 << entry->url(); |
| 268 delete entry; | 268 delete entry; |
| 269 return; | 269 return; |
| 270 } | 270 } |
| 271 | 271 |
| 272 // When navigating to a new page, we don't know for sure if we will actually | 272 // When navigating to a new page, we don't know for sure if we will actually |
| 273 // end up leaving the current page. The new page load could for example | 273 // end up leaving the current page. The new page load could for example |
| 274 // result in a download or a 'no content' response (e.g., a mailto: URL). | 274 // result in a download or a 'no content' response (e.g., a mailto: URL). |
| 275 DiscardNonCommittedEntriesInternal(); | 275 DiscardNonCommittedEntriesInternal(); |
| 276 pending_entry_ = entry; | 276 pending_entry_ = entry; |
| 277 NotificationService::current()->Notify( | 277 content::NotificationService::current()->Notify( |
| 278 content::NOTIFICATION_NAV_ENTRY_PENDING, | 278 content::NOTIFICATION_NAV_ENTRY_PENDING, |
| 279 content::Source<NavigationController>(this), | 279 content::Source<NavigationController>(this), |
| 280 content::Details<NavigationEntry>(entry)); | 280 content::Details<NavigationEntry>(entry)); |
| 281 NavigateToPendingEntry(NO_RELOAD); | 281 NavigateToPendingEntry(NO_RELOAD); |
| 282 } | 282 } |
| 283 | 283 |
| 284 NavigationEntry* NavigationController::GetActiveEntry() const { | 284 NavigationEntry* NavigationController::GetActiveEntry() const { |
| 285 if (transient_entry_index_ != -1) | 285 if (transient_entry_index_ != -1) |
| 286 return entries_[transient_entry_index_].get(); | 286 return entries_[transient_entry_index_].get(); |
| 287 if (pending_entry_) | 287 if (pending_entry_) |
| (...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1132 // We need to notify the ssl_manager_ before the tab_contents_ so the | 1132 // We need to notify the ssl_manager_ before the tab_contents_ so the |
| 1133 // location bar will have up-to-date information about the security style | 1133 // location bar will have up-to-date information about the security style |
| 1134 // when it wants to draw. See http://crbug.com/11157 | 1134 // when it wants to draw. See http://crbug.com/11157 |
| 1135 ssl_manager_.DidCommitProvisionalLoad(notification_details); | 1135 ssl_manager_.DidCommitProvisionalLoad(notification_details); |
| 1136 | 1136 |
| 1137 // TODO(pkasting): http://b/1113079 Probably these explicit notification paths | 1137 // TODO(pkasting): http://b/1113079 Probably these explicit notification paths |
| 1138 // should be removed, and interested parties should just listen for the | 1138 // should be removed, and interested parties should just listen for the |
| 1139 // notification below instead. | 1139 // notification below instead. |
| 1140 tab_contents_->NotifyNavigationStateChanged(kInvalidateAll); | 1140 tab_contents_->NotifyNavigationStateChanged(kInvalidateAll); |
| 1141 | 1141 |
| 1142 NotificationService::current()->Notify( | 1142 content::NotificationService::current()->Notify( |
| 1143 content::NOTIFICATION_NAV_ENTRY_COMMITTED, | 1143 content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
| 1144 content::Source<NavigationController>(this), | 1144 content::Source<NavigationController>(this), |
| 1145 notification_details); | 1145 notification_details); |
| 1146 } | 1146 } |
| 1147 | 1147 |
| 1148 // static | 1148 // static |
| 1149 void NavigationController::DisablePromptOnRepost() { | 1149 void NavigationController::DisablePromptOnRepost() { |
| 1150 check_for_repost_ = false; | 1150 check_for_repost_ = false; |
| 1151 } | 1151 } |
| 1152 | 1152 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1164 // cached state. | 1164 // cached state. |
| 1165 pending_entry_index_ = last_committed_entry_index_; | 1165 pending_entry_index_ = last_committed_entry_index_; |
| 1166 NavigateToPendingEntry(NO_RELOAD); | 1166 NavigateToPendingEntry(NO_RELOAD); |
| 1167 } | 1167 } |
| 1168 | 1168 |
| 1169 void NavigationController::NotifyEntryChanged(const NavigationEntry* entry, | 1169 void NavigationController::NotifyEntryChanged(const NavigationEntry* entry, |
| 1170 int index) { | 1170 int index) { |
| 1171 content::EntryChangedDetails det; | 1171 content::EntryChangedDetails det; |
| 1172 det.changed_entry = entry; | 1172 det.changed_entry = entry; |
| 1173 det.index = index; | 1173 det.index = index; |
| 1174 NotificationService::current()->Notify( | 1174 content::NotificationService::current()->Notify( |
| 1175 content::NOTIFICATION_NAV_ENTRY_CHANGED, | 1175 content::NOTIFICATION_NAV_ENTRY_CHANGED, |
| 1176 content::Source<NavigationController>(this), | 1176 content::Source<NavigationController>(this), |
| 1177 content::Details<content::EntryChangedDetails>(&det)); | 1177 content::Details<content::EntryChangedDetails>(&det)); |
| 1178 } | 1178 } |
| 1179 | 1179 |
| 1180 void NavigationController::FinishRestore(int selected_index, | 1180 void NavigationController::FinishRestore(int selected_index, |
| 1181 bool from_last_session) { | 1181 bool from_last_session) { |
| 1182 DCHECK(selected_index >= 0 && selected_index < entry_count()); | 1182 DCHECK(selected_index >= 0 && selected_index < entry_count()); |
| 1183 ConfigureEntriesForRestore(&entries_, from_last_session); | 1183 ConfigureEntriesForRestore(&entries_, from_last_session); |
| 1184 | 1184 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1229 for (int i = 0; i < max_index; i++) { | 1229 for (int i = 0; i < max_index; i++) { |
| 1230 // When cloning a tab, copy all entries except interstitial pages | 1230 // When cloning a tab, copy all entries except interstitial pages |
| 1231 if (source.entries_[i].get()->page_type() != | 1231 if (source.entries_[i].get()->page_type() != |
| 1232 content::PAGE_TYPE_INTERSTITIAL) { | 1232 content::PAGE_TYPE_INTERSTITIAL) { |
| 1233 entries_.insert(entries_.begin() + insert_index++, | 1233 entries_.insert(entries_.begin() + insert_index++, |
| 1234 linked_ptr<NavigationEntry>( | 1234 linked_ptr<NavigationEntry>( |
| 1235 new NavigationEntry(*source.entries_[i]))); | 1235 new NavigationEntry(*source.entries_[i]))); |
| 1236 } | 1236 } |
| 1237 } | 1237 } |
| 1238 } | 1238 } |
| OLD | NEW |