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 |