| 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_number_conversions.h" // Temporary | 9 #include "base/string_number_conversions.h" // Temporary |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| 11 #include "base/time.h" | 11 #include "base/time.h" |
| 12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.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/renderer_host/render_view_host.h" // Temporary | 16 #include "content/browser/renderer_host/render_view_host.h" // Temporary |
| 17 #include "content/browser/site_instance.h" | 17 #include "content/browser/site_instance.h" |
| 18 #include "content/browser/tab_contents/interstitial_page.h" | 18 #include "content/browser/tab_contents/interstitial_page.h" |
| 19 #include "content/browser/tab_contents/navigation_entry.h" | 19 #include "content/browser/tab_contents/navigation_entry_impl.h" |
| 20 #include "content/browser/tab_contents/tab_contents.h" | 20 #include "content/browser/tab_contents/tab_contents.h" |
| 21 #include "content/common/view_messages.h" | 21 #include "content/common/view_messages.h" |
| 22 #include "content/public/browser/browser_context.h" | 22 #include "content/public/browser/browser_context.h" |
| 23 #include "content/public/browser/navigation_details.h" | 23 #include "content/public/browser/navigation_details.h" |
| 24 #include "content/public/browser/notification_service.h" | 24 #include "content/public/browser/notification_service.h" |
| 25 #include "content/public/browser/notification_types.h" | 25 #include "content/public/browser/notification_types.h" |
| 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::GlobalRequestID; | 34 using content::GlobalRequestID; |
| 35 using content::NavigationEntry; |
| 36 using content::NavigationEntryImpl; |
| 35 using content::UserMetricsAction; | 37 using content::UserMetricsAction; |
| 36 | 38 |
| 37 namespace { | 39 namespace { |
| 38 | 40 |
| 39 const int kInvalidateAll = 0xFFFFFFFF; | 41 const int kInvalidateAll = 0xFFFFFFFF; |
| 40 | 42 |
| 41 // Invoked when entries have been pruned, or removed. For example, if the | 43 // Invoked when entries have been pruned, or removed. For example, if the |
| 42 // current entries are [google, digg, yahoo], with the current entry google, | 44 // current entries are [google, digg, yahoo], with the current entry google, |
| 43 // and the user types in cnet, then digg and yahoo are pruned. | 45 // and the user types in cnet, then digg and yahoo are pruned. |
| 44 void NotifyPrunedEntries(NavigationController* nav_controller, | 46 void NotifyPrunedEntries(NavigationController* nav_controller, |
| 45 bool from_front, | 47 bool from_front, |
| 46 int count) { | 48 int count) { |
| 47 content::PrunedDetails details; | 49 content::PrunedDetails details; |
| 48 details.from_front = from_front; | 50 details.from_front = from_front; |
| 49 details.count = count; | 51 details.count = count; |
| 50 content::NotificationService::current()->Notify( | 52 content::NotificationService::current()->Notify( |
| 51 content::NOTIFICATION_NAV_LIST_PRUNED, | 53 content::NOTIFICATION_NAV_LIST_PRUNED, |
| 52 content::Source<NavigationController>(nav_controller), | 54 content::Source<NavigationController>(nav_controller), |
| 53 content::Details<content::PrunedDetails>(&details)); | 55 content::Details<content::PrunedDetails>(&details)); |
| 54 } | 56 } |
| 55 | 57 |
| 56 // Ensure the given NavigationEntry has a valid state, so that WebKit does not | 58 // Ensure the given NavigationEntry has a valid state, so that WebKit does not |
| 57 // get confused if we navigate back to it. | 59 // get confused if we navigate back to it. |
| 58 // | 60 // |
| 59 // An empty state is treated as a new navigation by WebKit, which would mean | 61 // An empty state is treated as a new navigation by WebKit, which would mean |
| 60 // losing the navigation entries and generating a new navigation entry after | 62 // losing the navigation entries and generating a new navigation entry after |
| 61 // this one. We don't want that. To avoid this we create a valid state which | 63 // this one. We don't want that. To avoid this we create a valid state which |
| 62 // WebKit will not treat as a new navigation. | 64 // WebKit will not treat as a new navigation. |
| 63 void SetContentStateIfEmpty(NavigationEntry* entry) { | 65 void SetContentStateIfEmpty(NavigationEntryImpl* entry) { |
| 64 if (entry->GetContentState().empty()) { | 66 if (entry->GetContentState().empty()) { |
| 65 entry->SetContentState( | 67 entry->SetContentState( |
| 66 webkit_glue::CreateHistoryStateForURL(entry->GetURL())); | 68 webkit_glue::CreateHistoryStateForURL(entry->GetURL())); |
| 67 } | 69 } |
| 68 } | 70 } |
| 69 | 71 |
| 70 // Configure all the NavigationEntries in entries for restore. This resets | 72 // Configure all the NavigationEntries in entries for restore. This resets |
| 71 // the transition type to reload and makes sure the content state isn't empty. | 73 // the transition type to reload and makes sure the content state isn't empty. |
| 72 void ConfigureEntriesForRestore( | 74 void ConfigureEntriesForRestore( |
| 73 std::vector<linked_ptr<NavigationEntry> >* entries, | 75 std::vector<linked_ptr<NavigationEntryImpl> >* entries, |
| 74 bool from_last_session) { | 76 bool from_last_session) { |
| 75 for (size_t i = 0; i < entries->size(); ++i) { | 77 for (size_t i = 0; i < entries->size(); ++i) { |
| 76 // Use a transition type of reload so that we don't incorrectly increase | 78 // Use a transition type of reload so that we don't incorrectly increase |
| 77 // the typed count. | 79 // the typed count. |
| 78 (*entries)[i]->SetTransitionType(content::PAGE_TRANSITION_RELOAD); | 80 (*entries)[i]->SetTransitionType(content::PAGE_TRANSITION_RELOAD); |
| 79 (*entries)[i]->set_restore_type(from_last_session ? | 81 (*entries)[i]->set_restore_type(from_last_session ? |
| 80 NavigationEntry::RESTORE_LAST_SESSION : | 82 NavigationEntryImpl::RESTORE_LAST_SESSION : |
| 81 NavigationEntry::RESTORE_CURRENT_SESSION); | 83 NavigationEntryImpl::RESTORE_CURRENT_SESSION); |
| 82 // NOTE(darin): This code is only needed for backwards compat. | 84 // NOTE(darin): This code is only needed for backwards compat. |
| 83 SetContentStateIfEmpty((*entries)[i].get()); | 85 SetContentStateIfEmpty((*entries)[i].get()); |
| 84 } | 86 } |
| 85 } | 87 } |
| 86 | 88 |
| 87 // See NavigationController::IsURLInPageNavigation for how this works and why. | 89 // See NavigationController::IsURLInPageNavigation for how this works and why. |
| 88 bool AreURLsInPageNavigation(const GURL& existing_url, const GURL& new_url) { | 90 bool AreURLsInPageNavigation(const GURL& existing_url, const GURL& new_url) { |
| 89 if (existing_url == new_url || !new_url.has_ref()) { | 91 if (existing_url == new_url || !new_url.has_ref()) { |
| 90 // TODO(jcampan): what about when navigating back from a ref URL to the top | 92 // TODO(jcampan): what about when navigating back from a ref URL to the top |
| 91 // non ref URL? Nothing is loaded in that case but we return false here. | 93 // non ref URL? Nothing is loaded in that case but we return false here. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 | 144 |
| 143 content::NotificationService::current()->Notify( | 145 content::NotificationService::current()->Notify( |
| 144 content::NOTIFICATION_TAB_CLOSED, | 146 content::NOTIFICATION_TAB_CLOSED, |
| 145 content::Source<NavigationController>(this), | 147 content::Source<NavigationController>(this), |
| 146 content::NotificationService::NoDetails()); | 148 content::NotificationService::NoDetails()); |
| 147 } | 149 } |
| 148 | 150 |
| 149 void NavigationController::Restore( | 151 void NavigationController::Restore( |
| 150 int selected_navigation, | 152 int selected_navigation, |
| 151 bool from_last_session, | 153 bool from_last_session, |
| 152 std::vector<content::NavigationEntry*>* entries) { | 154 std::vector<NavigationEntry*>* entries) { |
| 153 // Verify that this controller is unused and that the input is valid. | 155 // Verify that this controller is unused and that the input is valid. |
| 154 DCHECK(entry_count() == 0 && !GetPendingEntry()); | 156 DCHECK(entry_count() == 0 && !GetPendingEntry()); |
| 155 DCHECK(selected_navigation >= 0 && | 157 DCHECK(selected_navigation >= 0 && |
| 156 selected_navigation < static_cast<int>(entries->size())); | 158 selected_navigation < static_cast<int>(entries->size())); |
| 157 | 159 |
| 158 needs_reload_ = true; | 160 needs_reload_ = true; |
| 159 for (size_t i = 0; i < entries->size(); ++i) { | 161 for (size_t i = 0; i < entries->size(); ++i) { |
| 160 NavigationEntry* entry = | 162 NavigationEntryImpl* entry = |
| 161 NavigationEntry::FromNavigationEntry((*entries)[i]); | 163 NavigationEntryImpl::FromNavigationEntry((*entries)[i]); |
| 162 entries_.push_back(linked_ptr<NavigationEntry>(entry)); | 164 entries_.push_back(linked_ptr<NavigationEntryImpl>(entry)); |
| 163 } | 165 } |
| 164 entries->clear(); | 166 entries->clear(); |
| 165 | 167 |
| 166 // And finish the restore. | 168 // And finish the restore. |
| 167 FinishRestore(selected_navigation, from_last_session); | 169 FinishRestore(selected_navigation, from_last_session); |
| 168 } | 170 } |
| 169 | 171 |
| 170 void NavigationController::Reload(bool check_for_repost) { | 172 void NavigationController::Reload(bool check_for_repost) { |
| 171 ReloadInternal(check_for_repost, RELOAD); | 173 ReloadInternal(check_for_repost, RELOAD); |
| 172 } | 174 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 ReloadInternal(false, pending_reload_); | 225 ReloadInternal(false, pending_reload_); |
| 224 pending_reload_ = NO_RELOAD; | 226 pending_reload_ = NO_RELOAD; |
| 225 } | 227 } |
| 226 } | 228 } |
| 227 | 229 |
| 228 bool NavigationController::IsInitialNavigation() { | 230 bool NavigationController::IsInitialNavigation() { |
| 229 return last_document_loaded_.is_null(); | 231 return last_document_loaded_.is_null(); |
| 230 } | 232 } |
| 231 | 233 |
| 232 // static | 234 // static |
| 233 content::NavigationEntry* NavigationController::CreateNavigationEntry( | 235 NavigationEntry* NavigationController::CreateNavigationEntry( |
| 234 const GURL& url, | 236 const GURL& url, |
| 235 const content::Referrer& referrer, | 237 const content::Referrer& referrer, |
| 236 content::PageTransition transition, | 238 content::PageTransition transition, |
| 237 bool is_renderer_initiated, | 239 bool is_renderer_initiated, |
| 238 const std::string& extra_headers, | 240 const std::string& extra_headers, |
| 239 content::BrowserContext* browser_context) { | 241 content::BrowserContext* browser_context) { |
| 240 return CreateNavigationEntryImpl( | 242 return CreateNavigationEntryImpl( |
| 241 url, referrer, transition, is_renderer_initiated, extra_headers, | 243 url, referrer, transition, is_renderer_initiated, extra_headers, |
| 242 browser_context); | 244 browser_context); |
| 243 } | 245 } |
| 244 | 246 |
| 245 // static | 247 // static |
| 246 NavigationEntry* NavigationController::CreateNavigationEntryImpl( | 248 NavigationEntryImpl* NavigationController::CreateNavigationEntryImpl( |
| 247 const GURL& url, const content::Referrer& referrer, | 249 const GURL& url, const content::Referrer& referrer, |
| 248 content::PageTransition transition, | 250 content::PageTransition transition, |
| 249 bool is_renderer_initiated, const std::string& extra_headers, | 251 bool is_renderer_initiated, const std::string& extra_headers, |
| 250 content::BrowserContext* browser_context) { | 252 content::BrowserContext* browser_context) { |
| 251 // Allow the browser URL handler to rewrite the URL. This will, for example, | 253 // Allow the browser URL handler to rewrite the URL. This will, for example, |
| 252 // remove "view-source:" from the beginning of the URL to get the URL that | 254 // remove "view-source:" from the beginning of the URL to get the URL that |
| 253 // will actually be loaded. This real URL won't be shown to the user, just | 255 // will actually be loaded. This real URL won't be shown to the user, just |
| 254 // used internally. | 256 // used internally. |
| 255 GURL loaded_url(url); | 257 GURL loaded_url(url); |
| 256 bool reverse_on_redirect = false; | 258 bool reverse_on_redirect = false; |
| 257 BrowserURLHandler::GetInstance()->RewriteURLIfNecessary( | 259 BrowserURLHandler::GetInstance()->RewriteURLIfNecessary( |
| 258 &loaded_url, browser_context, &reverse_on_redirect); | 260 &loaded_url, browser_context, &reverse_on_redirect); |
| 259 | 261 |
| 260 NavigationEntry* entry = new NavigationEntry( | 262 NavigationEntryImpl* entry = new NavigationEntryImpl( |
| 261 NULL, // The site instance for tabs is sent on navigation | 263 NULL, // The site instance for tabs is sent on navigation |
| 262 // (TabContents::GetSiteInstance). | 264 // (TabContents::GetSiteInstance). |
| 263 -1, | 265 -1, |
| 264 loaded_url, | 266 loaded_url, |
| 265 referrer, | 267 referrer, |
| 266 string16(), | 268 string16(), |
| 267 transition, | 269 transition, |
| 268 is_renderer_initiated); | 270 is_renderer_initiated); |
| 269 entry->SetVirtualURL(url); | 271 entry->SetVirtualURL(url); |
| 270 entry->set_user_typed_url(url); | 272 entry->set_user_typed_url(url); |
| 271 entry->set_update_virtual_url_with_url(reverse_on_redirect); | 273 entry->set_update_virtual_url_with_url(reverse_on_redirect); |
| 272 entry->set_extra_headers(extra_headers); | 274 entry->set_extra_headers(extra_headers); |
| 273 return entry; | 275 return entry; |
| 274 } | 276 } |
| 275 | 277 |
| 276 NavigationEntry* NavigationController::GetEntryWithPageID( | 278 NavigationEntryImpl* NavigationController::GetEntryWithPageID( |
| 277 SiteInstance* instance, int32 page_id) const { | 279 SiteInstance* instance, int32 page_id) const { |
| 278 int index = GetEntryIndexWithPageID(instance, page_id); | 280 int index = GetEntryIndexWithPageID(instance, page_id); |
| 279 return (index != -1) ? entries_[index].get() : NULL; | 281 return (index != -1) ? entries_[index].get() : NULL; |
| 280 } | 282 } |
| 281 | 283 |
| 282 void NavigationController::LoadEntry(NavigationEntry* entry) { | 284 void NavigationController::LoadEntry(NavigationEntryImpl* entry) { |
| 283 // Don't navigate to URLs disabled by policy. This prevents showing the URL | 285 // Don't navigate to URLs disabled by policy. This prevents showing the URL |
| 284 // on the Omnibar when it is also going to be blocked by | 286 // on the Omnibar when it is also going to be blocked by |
| 285 // ChildProcessSecurityPolicy::CanRequestURL. | 287 // ChildProcessSecurityPolicy::CanRequestURL. |
| 286 ChildProcessSecurityPolicy *policy = | 288 ChildProcessSecurityPolicy *policy = |
| 287 ChildProcessSecurityPolicy::GetInstance(); | 289 ChildProcessSecurityPolicy::GetInstance(); |
| 288 if (policy->IsDisabledScheme(entry->GetURL().scheme()) || | 290 if (policy->IsDisabledScheme(entry->GetURL().scheme()) || |
| 289 policy->IsDisabledScheme(entry->GetVirtualURL().scheme())) { | 291 policy->IsDisabledScheme(entry->GetVirtualURL().scheme())) { |
| 290 VLOG(1) << "URL not loaded because the scheme is blocked by policy: " | 292 VLOG(1) << "URL not loaded because the scheme is blocked by policy: " |
| 291 << entry->GetURL(); | 293 << entry->GetURL(); |
| 292 delete entry; | 294 delete entry; |
| 293 return; | 295 return; |
| 294 } | 296 } |
| 295 | 297 |
| 296 // When navigating to a new page, we don't know for sure if we will actually | 298 // When navigating to a new page, we don't know for sure if we will actually |
| 297 // end up leaving the current page. The new page load could for example | 299 // end up leaving the current page. The new page load could for example |
| 298 // result in a download or a 'no content' response (e.g., a mailto: URL). | 300 // result in a download or a 'no content' response (e.g., a mailto: URL). |
| 299 DiscardNonCommittedEntriesInternal(); | 301 DiscardNonCommittedEntriesInternal(); |
| 300 pending_entry_ = entry; | 302 pending_entry_ = entry; |
| 301 content::NotificationService::current()->Notify( | 303 content::NotificationService::current()->Notify( |
| 302 content::NOTIFICATION_NAV_ENTRY_PENDING, | 304 content::NOTIFICATION_NAV_ENTRY_PENDING, |
| 303 content::Source<NavigationController>(this), | 305 content::Source<NavigationController>(this), |
| 304 content::Details<content::NavigationEntry>(entry)); | 306 content::Details<NavigationEntry>(entry)); |
| 305 NavigateToPendingEntry(NO_RELOAD); | 307 NavigateToPendingEntry(NO_RELOAD); |
| 306 } | 308 } |
| 307 | 309 |
| 308 content::NavigationEntry* NavigationController::GetActiveEntry() const { | 310 NavigationEntry* NavigationController::GetActiveEntry() const { |
| 309 if (transient_entry_index_ != -1) | 311 if (transient_entry_index_ != -1) |
| 310 return entries_[transient_entry_index_].get(); | 312 return entries_[transient_entry_index_].get(); |
| 311 if (pending_entry_) | 313 if (pending_entry_) |
| 312 return pending_entry_; | 314 return pending_entry_; |
| 313 return GetLastCommittedEntry(); | 315 return GetLastCommittedEntry(); |
| 314 } | 316 } |
| 315 | 317 |
| 316 content::NavigationEntry* NavigationController::GetVisibleEntry() const { | 318 NavigationEntry* NavigationController::GetVisibleEntry() const { |
| 317 if (transient_entry_index_ != -1) | 319 if (transient_entry_index_ != -1) |
| 318 return entries_[transient_entry_index_].get(); | 320 return entries_[transient_entry_index_].get(); |
| 319 // Only return the pending_entry for new (non-history), browser-initiated | 321 // Only return the pending_entry for new (non-history), browser-initiated |
| 320 // navigations, in order to prevent URL spoof attacks. | 322 // navigations, in order to prevent URL spoof attacks. |
| 321 // Ideally we would also show the pending entry's URL for new renderer- | 323 // Ideally we would also show the pending entry's URL for new renderer- |
| 322 // initiated navigations with no last committed entry (e.g., a link opening | 324 // initiated navigations with no last committed entry (e.g., a link opening |
| 323 // in a new tab), but an attacker can insert content into the about:blank | 325 // in a new tab), but an attacker can insert content into the about:blank |
| 324 // page while the pending URL loads in that case. | 326 // page while the pending URL loads in that case. |
| 325 if (pending_entry_ && | 327 if (pending_entry_ && |
| 326 pending_entry_->GetPageID() == -1 && | 328 pending_entry_->GetPageID() == -1 && |
| 327 !pending_entry_->is_renderer_initiated()) | 329 !pending_entry_->is_renderer_initiated()) |
| 328 return pending_entry_; | 330 return pending_entry_; |
| 329 return GetLastCommittedEntry(); | 331 return GetLastCommittedEntry(); |
| 330 } | 332 } |
| 331 | 333 |
| 332 int NavigationController::GetCurrentEntryIndex() const { | 334 int NavigationController::GetCurrentEntryIndex() const { |
| 333 if (transient_entry_index_ != -1) | 335 if (transient_entry_index_ != -1) |
| 334 return transient_entry_index_; | 336 return transient_entry_index_; |
| 335 if (pending_entry_index_ != -1) | 337 if (pending_entry_index_ != -1) |
| 336 return pending_entry_index_; | 338 return pending_entry_index_; |
| 337 return last_committed_entry_index_; | 339 return last_committed_entry_index_; |
| 338 } | 340 } |
| 339 | 341 |
| 340 content::NavigationEntry* NavigationController::GetLastCommittedEntry() const { | 342 NavigationEntry* NavigationController::GetLastCommittedEntry() const { |
| 341 if (last_committed_entry_index_ == -1) | 343 if (last_committed_entry_index_ == -1) |
| 342 return NULL; | 344 return NULL; |
| 343 return entries_[last_committed_entry_index_].get(); | 345 return entries_[last_committed_entry_index_].get(); |
| 344 } | 346 } |
| 345 | 347 |
| 346 bool NavigationController::CanViewSource() const { | 348 bool NavigationController::CanViewSource() const { |
| 347 bool is_supported_mime_type = net::IsSupportedNonImageMimeType( | 349 bool is_supported_mime_type = net::IsSupportedNonImageMimeType( |
| 348 tab_contents_->GetContentsMimeType().c_str()); | 350 tab_contents_->GetContentsMimeType().c_str()); |
| 349 content::NavigationEntry* active_entry = GetActiveEntry(); | 351 NavigationEntry* active_entry = GetActiveEntry(); |
| 350 return active_entry && !active_entry->IsViewSourceMode() && | 352 return active_entry && !active_entry->IsViewSourceMode() && |
| 351 is_supported_mime_type && !tab_contents_->GetInterstitialPage(); | 353 is_supported_mime_type && !tab_contents_->GetInterstitialPage(); |
| 352 } | 354 } |
| 353 | 355 |
| 354 content::NavigationEntry* NavigationController::GetEntryAtIndex( | 356 NavigationEntry* NavigationController::GetEntryAtIndex( |
| 355 int index) const { | 357 int index) const { |
| 356 return entries_.at(index).get(); | 358 return entries_.at(index).get(); |
| 357 } | 359 } |
| 358 | 360 |
| 359 content::NavigationEntry* NavigationController::GetEntryAtOffset( | 361 NavigationEntry* NavigationController::GetEntryAtOffset( |
| 360 int offset) const { | 362 int offset) const { |
| 361 int index = (transient_entry_index_ != -1) ? | 363 int index = (transient_entry_index_ != -1) ? |
| 362 transient_entry_index_ + offset : | 364 transient_entry_index_ + offset : |
| 363 last_committed_entry_index_ + offset; | 365 last_committed_entry_index_ + offset; |
| 364 if (index < 0 || index >= entry_count()) | 366 if (index < 0 || index >= entry_count()) |
| 365 return NULL; | 367 return NULL; |
| 366 | 368 |
| 367 return entries_[index].get(); | 369 return entries_[index].get(); |
| 368 } | 370 } |
| 369 | 371 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 } | 461 } |
| 460 | 462 |
| 461 void NavigationController::RemoveEntryAtIndex(int index) { | 463 void NavigationController::RemoveEntryAtIndex(int index) { |
| 462 if (index == last_committed_entry_index_) | 464 if (index == last_committed_entry_index_) |
| 463 return; | 465 return; |
| 464 | 466 |
| 465 RemoveEntryAtIndexInternal(index); | 467 RemoveEntryAtIndexInternal(index); |
| 466 } | 468 } |
| 467 | 469 |
| 468 void NavigationController::UpdateVirtualURLToURL( | 470 void NavigationController::UpdateVirtualURLToURL( |
| 469 NavigationEntry* entry, const GURL& new_url) { | 471 NavigationEntryImpl* entry, const GURL& new_url) { |
| 470 GURL new_virtual_url(new_url); | 472 GURL new_virtual_url(new_url); |
| 471 if (BrowserURLHandler::GetInstance()->ReverseURLRewrite( | 473 if (BrowserURLHandler::GetInstance()->ReverseURLRewrite( |
| 472 &new_virtual_url, entry->GetVirtualURL(), browser_context_)) { | 474 &new_virtual_url, entry->GetVirtualURL(), browser_context_)) { |
| 473 entry->SetVirtualURL(new_virtual_url); | 475 entry->SetVirtualURL(new_virtual_url); |
| 474 } | 476 } |
| 475 } | 477 } |
| 476 | 478 |
| 477 void NavigationController::AddTransientEntry(NavigationEntry* entry) { | 479 void NavigationController::AddTransientEntry(NavigationEntryImpl* entry) { |
| 478 // Discard any current transient entry, we can only have one at a time. | 480 // Discard any current transient entry, we can only have one at a time. |
| 479 int index = 0; | 481 int index = 0; |
| 480 if (last_committed_entry_index_ != -1) | 482 if (last_committed_entry_index_ != -1) |
| 481 index = last_committed_entry_index_ + 1; | 483 index = last_committed_entry_index_ + 1; |
| 482 DiscardTransientEntry(); | 484 DiscardTransientEntry(); |
| 483 entries_.insert(entries_.begin() + index, linked_ptr<NavigationEntry>(entry)); | 485 entries_.insert( |
| 486 entries_.begin() + index, linked_ptr<NavigationEntryImpl>(entry)); |
| 484 transient_entry_index_ = index; | 487 transient_entry_index_ = index; |
| 485 tab_contents_->NotifyNavigationStateChanged(kInvalidateAll); | 488 tab_contents_->NotifyNavigationStateChanged(kInvalidateAll); |
| 486 } | 489 } |
| 487 | 490 |
| 488 void NavigationController::TransferURL( | 491 void NavigationController::TransferURL( |
| 489 const GURL& url, | 492 const GURL& url, |
| 490 const content::Referrer& referrer, | 493 const content::Referrer& referrer, |
| 491 content::PageTransition transition, | 494 content::PageTransition transition, |
| 492 const std::string& extra_headers, | 495 const std::string& extra_headers, |
| 493 const GlobalRequestID& transferred_global_request_id, | 496 const GlobalRequestID& transferred_global_request_id, |
| 494 bool is_renderer_initiated) { | 497 bool is_renderer_initiated) { |
| 495 // The user initiated a load, we don't need to reload anymore. | 498 // The user initiated a load, we don't need to reload anymore. |
| 496 needs_reload_ = false; | 499 needs_reload_ = false; |
| 497 | 500 |
| 498 NavigationEntry* entry = CreateNavigationEntryImpl(url, referrer, transition, | 501 NavigationEntryImpl* entry = CreateNavigationEntryImpl( |
| 499 is_renderer_initiated, | 502 url, referrer, transition, is_renderer_initiated, extra_headers, |
| 500 extra_headers, | 503 browser_context_); |
| 501 browser_context_); | |
| 502 entry->set_transferred_global_request_id(transferred_global_request_id); | 504 entry->set_transferred_global_request_id(transferred_global_request_id); |
| 503 | 505 |
| 504 LoadEntry(entry); | 506 LoadEntry(entry); |
| 505 } | 507 } |
| 506 | 508 |
| 507 void NavigationController::LoadURL( | 509 void NavigationController::LoadURL( |
| 508 const GURL& url, | 510 const GURL& url, |
| 509 const content::Referrer& referrer, | 511 const content::Referrer& referrer, |
| 510 content::PageTransition transition, | 512 content::PageTransition transition, |
| 511 const std::string& extra_headers) { | 513 const std::string& extra_headers) { |
| 512 // The user initiated a load, we don't need to reload anymore. | 514 // The user initiated a load, we don't need to reload anymore. |
| 513 needs_reload_ = false; | 515 needs_reload_ = false; |
| 514 | 516 |
| 515 NavigationEntry* entry = CreateNavigationEntryImpl(url, referrer, transition, | 517 NavigationEntryImpl* entry = CreateNavigationEntryImpl( |
| 516 false, | 518 url, referrer, transition, false, extra_headers, browser_context_); |
| 517 extra_headers, | |
| 518 browser_context_); | |
| 519 | 519 |
| 520 LoadEntry(entry); | 520 LoadEntry(entry); |
| 521 } | 521 } |
| 522 | 522 |
| 523 void NavigationController::LoadURLFromRenderer( | 523 void NavigationController::LoadURLFromRenderer( |
| 524 const GURL& url, | 524 const GURL& url, |
| 525 const content::Referrer& referrer, | 525 const content::Referrer& referrer, |
| 526 content::PageTransition transition, | 526 content::PageTransition transition, |
| 527 const std::string& extra_headers) { | 527 const std::string& extra_headers) { |
| 528 // The user initiated a load, we don't need to reload anymore. | 528 // The user initiated a load, we don't need to reload anymore. |
| 529 needs_reload_ = false; | 529 needs_reload_ = false; |
| 530 | 530 |
| 531 NavigationEntry* entry = CreateNavigationEntryImpl(url, referrer, transition, | 531 NavigationEntryImpl* entry = CreateNavigationEntryImpl( |
| 532 true, | 532 url, referrer, transition, true, extra_headers, browser_context_); |
| 533 extra_headers, | |
| 534 browser_context_); | |
| 535 | 533 |
| 536 LoadEntry(entry); | 534 LoadEntry(entry); |
| 537 } | 535 } |
| 538 | 536 |
| 539 void NavigationController::DocumentLoadedInFrame() { | 537 void NavigationController::DocumentLoadedInFrame() { |
| 540 last_document_loaded_ = base::TimeTicks::Now(); | 538 last_document_loaded_ = base::TimeTicks::Now(); |
| 541 } | 539 } |
| 542 | 540 |
| 543 bool NavigationController::RendererDidNavigate( | 541 bool NavigationController::RendererDidNavigate( |
| 544 const ViewHostMsg_FrameNavigate_Params& params, | 542 const ViewHostMsg_FrameNavigate_Params& params, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 TabContents::INVALIDATE_URL); | 593 TabContents::INVALIDATE_URL); |
| 596 } | 594 } |
| 597 return false; | 595 return false; |
| 598 default: | 596 default: |
| 599 NOTREACHED(); | 597 NOTREACHED(); |
| 600 } | 598 } |
| 601 | 599 |
| 602 // All committed entries should have nonempty content state so WebKit doesn't | 600 // All committed entries should have nonempty content state so WebKit doesn't |
| 603 // get confused when we go back to them (see the function for details). | 601 // get confused when we go back to them (see the function for details). |
| 604 DCHECK(!params.content_state.empty()); | 602 DCHECK(!params.content_state.empty()); |
| 605 NavigationEntry* active_entry = | 603 NavigationEntryImpl* active_entry = |
| 606 NavigationEntry::FromNavigationEntry(GetActiveEntry()); | 604 NavigationEntryImpl::FromNavigationEntry(GetActiveEntry()); |
| 607 active_entry->SetContentState(params.content_state); | 605 active_entry->SetContentState(params.content_state); |
| 608 | 606 |
| 609 // Once committed, we do not need to track if the entry was initiated by | 607 // Once committed, we do not need to track if the entry was initiated by |
| 610 // the renderer. | 608 // the renderer. |
| 611 active_entry->set_is_renderer_initiated(false); | 609 active_entry->set_is_renderer_initiated(false); |
| 612 | 610 |
| 613 // The active entry's SiteInstance should match our SiteInstance. | 611 // The active entry's SiteInstance should match our SiteInstance. |
| 614 DCHECK(active_entry->site_instance() == tab_contents_->GetSiteInstance()); | 612 DCHECK(active_entry->site_instance() == tab_contents_->GetSiteInstance()); |
| 615 | 613 |
| 616 // Now prep the rest of the details for the notification and broadcast. | 614 // Now prep the rest of the details for the notification and broadcast. |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 else | 702 else |
| 705 temp.append("N"); | 703 temp.append("N"); |
| 706 if (entries_[i]->site_instance() != tab_contents_->GetSiteInstance()) | 704 if (entries_[i]->site_instance() != tab_contents_->GetSiteInstance()) |
| 707 temp.append("x"); | 705 temp.append("x"); |
| 708 temp.append(","); | 706 temp.append(","); |
| 709 } | 707 } |
| 710 GURL url(temp); | 708 GURL url(temp); |
| 711 tab_contents_->GetRenderViewHost()->Send(new ViewMsg_TempCrashWithData(url))
; | 709 tab_contents_->GetRenderViewHost()->Send(new ViewMsg_TempCrashWithData(url))
; |
| 712 return content::NAVIGATION_TYPE_NAV_IGNORE; | 710 return content::NAVIGATION_TYPE_NAV_IGNORE; |
| 713 } | 711 } |
| 714 NavigationEntry* existing_entry = entries_[existing_entry_index].get(); | 712 NavigationEntryImpl* existing_entry = entries_[existing_entry_index].get(); |
| 715 | 713 |
| 716 if (!content::PageTransitionIsMainFrame(params.transition)) { | 714 if (!content::PageTransitionIsMainFrame(params.transition)) { |
| 717 // All manual subframes would get new IDs and were handled above, so we | 715 // All manual subframes would get new IDs and were handled above, so we |
| 718 // know this is auto. Since the current page was found in the navigation | 716 // know this is auto. Since the current page was found in the navigation |
| 719 // entry list, we're guaranteed to have a last committed entry. | 717 // entry list, we're guaranteed to have a last committed entry. |
| 720 DCHECK(GetLastCommittedEntry()); | 718 DCHECK(GetLastCommittedEntry()); |
| 721 return content::NAVIGATION_TYPE_AUTO_SUBFRAME; | 719 return content::NAVIGATION_TYPE_AUTO_SUBFRAME; |
| 722 } | 720 } |
| 723 | 721 |
| 724 // Anything below here we know is a main frame navigation. | 722 // Anything below here we know is a main frame navigation. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 754 // For main frame transition, we judge by params.transition. | 752 // For main frame transition, we judge by params.transition. |
| 755 // Otherwise, by params.redirects. | 753 // Otherwise, by params.redirects. |
| 756 if (content::PageTransitionIsMainFrame(params.transition)) { | 754 if (content::PageTransitionIsMainFrame(params.transition)) { |
| 757 return content::PageTransitionIsRedirect(params.transition); | 755 return content::PageTransitionIsRedirect(params.transition); |
| 758 } | 756 } |
| 759 return params.redirects.size() > 1; | 757 return params.redirects.size() > 1; |
| 760 } | 758 } |
| 761 | 759 |
| 762 void NavigationController::RendererDidNavigateToNewPage( | 760 void NavigationController::RendererDidNavigateToNewPage( |
| 763 const ViewHostMsg_FrameNavigate_Params& params, bool* did_replace_entry) { | 761 const ViewHostMsg_FrameNavigate_Params& params, bool* did_replace_entry) { |
| 764 NavigationEntry* new_entry; | 762 NavigationEntryImpl* new_entry; |
| 765 bool update_virtual_url; | 763 bool update_virtual_url; |
| 766 if (pending_entry_) { | 764 if (pending_entry_) { |
| 767 // TODO(brettw) this assumes that the pending entry is appropriate for the | 765 // TODO(brettw) this assumes that the pending entry is appropriate for the |
| 768 // new page that was just loaded. I don't think this is necessarily the | 766 // new page that was just loaded. I don't think this is necessarily the |
| 769 // case! We should have some more tracking to know for sure. | 767 // case! We should have some more tracking to know for sure. |
| 770 new_entry = new NavigationEntry(*pending_entry_); | 768 new_entry = new NavigationEntryImpl(*pending_entry_); |
| 771 | 769 |
| 772 // Don't use the page type from the pending entry. Some interstitial page | 770 // Don't use the page type from the pending entry. Some interstitial page |
| 773 // may have set the type to interstitial. Once we commit, however, the page | 771 // may have set the type to interstitial. Once we commit, however, the page |
| 774 // type must always be normal. | 772 // type must always be normal. |
| 775 new_entry->set_page_type(content::PAGE_TYPE_NORMAL); | 773 new_entry->set_page_type(content::PAGE_TYPE_NORMAL); |
| 776 update_virtual_url = new_entry->update_virtual_url_with_url(); | 774 update_virtual_url = new_entry->update_virtual_url_with_url(); |
| 777 } else { | 775 } else { |
| 778 new_entry = new NavigationEntry; | 776 new_entry = new NavigationEntryImpl; |
| 779 // When navigating to a new page, give the browser URL handler a chance to | 777 // When navigating to a new page, give the browser URL handler a chance to |
| 780 // update the virtual URL based on the new URL. For example, this is needed | 778 // update the virtual URL based on the new URL. For example, this is needed |
| 781 // to show chrome://bookmarks/#1 when the bookmarks webui extension changes | 779 // to show chrome://bookmarks/#1 when the bookmarks webui extension changes |
| 782 // the URL. | 780 // the URL. |
| 783 update_virtual_url = true; | 781 update_virtual_url = true; |
| 784 } | 782 } |
| 785 | 783 |
| 786 new_entry->SetURL(params.url); | 784 new_entry->SetURL(params.url); |
| 787 if (update_virtual_url) | 785 if (update_virtual_url) |
| 788 UpdateVirtualURLToURL(new_entry, params.url); | 786 UpdateVirtualURLToURL(new_entry, params.url); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 800 // We should only get here for main frame navigations. | 798 // We should only get here for main frame navigations. |
| 801 DCHECK(content::PageTransitionIsMainFrame(params.transition)); | 799 DCHECK(content::PageTransitionIsMainFrame(params.transition)); |
| 802 | 800 |
| 803 // This is a back/forward navigation. The existing page for the ID is | 801 // This is a back/forward navigation. The existing page for the ID is |
| 804 // guaranteed to exist by ClassifyNavigation, and we just need to update it | 802 // guaranteed to exist by ClassifyNavigation, and we just need to update it |
| 805 // with new information from the renderer. | 803 // with new information from the renderer. |
| 806 int entry_index = GetEntryIndexWithPageID(tab_contents_->GetSiteInstance(), | 804 int entry_index = GetEntryIndexWithPageID(tab_contents_->GetSiteInstance(), |
| 807 params.page_id); | 805 params.page_id); |
| 808 DCHECK(entry_index >= 0 && | 806 DCHECK(entry_index >= 0 && |
| 809 entry_index < static_cast<int>(entries_.size())); | 807 entry_index < static_cast<int>(entries_.size())); |
| 810 NavigationEntry* entry = entries_[entry_index].get(); | 808 NavigationEntryImpl* entry = entries_[entry_index].get(); |
| 811 | 809 |
| 812 // The URL may have changed due to redirects. The site instance will normally | 810 // The URL may have changed due to redirects. The site instance will normally |
| 813 // be the same except during session restore, when no site instance will be | 811 // be the same except during session restore, when no site instance will be |
| 814 // assigned. | 812 // assigned. |
| 815 entry->SetURL(params.url); | 813 entry->SetURL(params.url); |
| 816 if (entry->update_virtual_url_with_url()) | 814 if (entry->update_virtual_url_with_url()) |
| 817 UpdateVirtualURLToURL(entry, params.url); | 815 UpdateVirtualURLToURL(entry, params.url); |
| 818 DCHECK(entry->site_instance() == NULL || | 816 DCHECK(entry->site_instance() == NULL || |
| 819 entry->site_instance() == tab_contents_->GetSiteInstance()); | 817 entry->site_instance() == tab_contents_->GetSiteInstance()); |
| 820 entry->set_site_instance(tab_contents_->GetSiteInstance()); | 818 entry->set_site_instance(tab_contents_->GetSiteInstance()); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 837 // have to query the entry index again. | 835 // have to query the entry index again. |
| 838 last_committed_entry_index_ = | 836 last_committed_entry_index_ = |
| 839 GetEntryIndexWithPageID(tab_contents_->GetSiteInstance(), params.page_id); | 837 GetEntryIndexWithPageID(tab_contents_->GetSiteInstance(), params.page_id); |
| 840 } | 838 } |
| 841 | 839 |
| 842 void NavigationController::RendererDidNavigateToSamePage( | 840 void NavigationController::RendererDidNavigateToSamePage( |
| 843 const ViewHostMsg_FrameNavigate_Params& params) { | 841 const ViewHostMsg_FrameNavigate_Params& params) { |
| 844 // This mode implies we have a pending entry that's the same as an existing | 842 // This mode implies we have a pending entry that's the same as an existing |
| 845 // entry for this page ID. This entry is guaranteed to exist by | 843 // entry for this page ID. This entry is guaranteed to exist by |
| 846 // ClassifyNavigation. All we need to do is update the existing entry. | 844 // ClassifyNavigation. All we need to do is update the existing entry. |
| 847 NavigationEntry* existing_entry = GetEntryWithPageID( | 845 NavigationEntryImpl* existing_entry = GetEntryWithPageID( |
| 848 tab_contents_->GetSiteInstance(), | 846 tab_contents_->GetSiteInstance(), params.page_id); |
| 849 params.page_id); | |
| 850 | 847 |
| 851 // We assign the entry's unique ID to be that of the new one. Since this is | 848 // We assign the entry's unique ID to be that of the new one. Since this is |
| 852 // always the result of a user action, we want to dismiss infobars, etc. like | 849 // always the result of a user action, we want to dismiss infobars, etc. like |
| 853 // a regular user-initiated navigation. | 850 // a regular user-initiated navigation. |
| 854 existing_entry->set_unique_id(pending_entry_->GetUniqueID()); | 851 existing_entry->set_unique_id(pending_entry_->GetUniqueID()); |
| 855 | 852 |
| 856 // The URL may have changed due to redirects. | 853 // The URL may have changed due to redirects. |
| 857 if (existing_entry->update_virtual_url_with_url()) | 854 if (existing_entry->update_virtual_url_with_url()) |
| 858 UpdateVirtualURLToURL(existing_entry, params.url); | 855 UpdateVirtualURLToURL(existing_entry, params.url); |
| 859 existing_entry->SetURL(params.url); | 856 existing_entry->SetURL(params.url); |
| 860 | 857 |
| 861 DiscardNonCommittedEntries(); | 858 DiscardNonCommittedEntries(); |
| 862 } | 859 } |
| 863 | 860 |
| 864 void NavigationController::RendererDidNavigateInPage( | 861 void NavigationController::RendererDidNavigateInPage( |
| 865 const ViewHostMsg_FrameNavigate_Params& params, bool* did_replace_entry) { | 862 const ViewHostMsg_FrameNavigate_Params& params, bool* did_replace_entry) { |
| 866 DCHECK(content::PageTransitionIsMainFrame(params.transition)) << | 863 DCHECK(content::PageTransitionIsMainFrame(params.transition)) << |
| 867 "WebKit should only tell us about in-page navs for the main frame."; | 864 "WebKit should only tell us about in-page navs for the main frame."; |
| 868 // We're guaranteed to have an entry for this one. | 865 // We're guaranteed to have an entry for this one. |
| 869 NavigationEntry* existing_entry = GetEntryWithPageID( | 866 NavigationEntryImpl* existing_entry = GetEntryWithPageID( |
| 870 tab_contents_->GetSiteInstance(), | 867 tab_contents_->GetSiteInstance(), params.page_id); |
| 871 params.page_id); | |
| 872 | 868 |
| 873 // Reference fragment navigation. We're guaranteed to have the last_committed | 869 // Reference fragment navigation. We're guaranteed to have the last_committed |
| 874 // entry and it will be the same page as the new navigation (minus the | 870 // entry and it will be the same page as the new navigation (minus the |
| 875 // reference fragments, of course). We'll update the URL of the existing | 871 // reference fragments, of course). We'll update the URL of the existing |
| 876 // entry without pruning the forward history. | 872 // entry without pruning the forward history. |
| 877 existing_entry->SetURL(params.url); | 873 existing_entry->SetURL(params.url); |
| 878 if (existing_entry->update_virtual_url_with_url()) | 874 if (existing_entry->update_virtual_url_with_url()) |
| 879 UpdateVirtualURLToURL(existing_entry, params.url); | 875 UpdateVirtualURLToURL(existing_entry, params.url); |
| 880 | 876 |
| 881 // This replaces the existing entry since the page ID didn't change. | 877 // This replaces the existing entry since the page ID didn't change. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 897 // This is not user-initiated. Ignore. | 893 // This is not user-initiated. Ignore. |
| 898 return; | 894 return; |
| 899 } | 895 } |
| 900 | 896 |
| 901 // Manual subframe navigations just get the current entry cloned so the user | 897 // Manual subframe navigations just get the current entry cloned so the user |
| 902 // can go back or forward to it. The actual subframe information will be | 898 // can go back or forward to it. The actual subframe information will be |
| 903 // stored in the page state for each of those entries. This happens out of | 899 // stored in the page state for each of those entries. This happens out of |
| 904 // band with the actual navigations. | 900 // band with the actual navigations. |
| 905 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " | 901 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " |
| 906 << "that a last committed entry exists."; | 902 << "that a last committed entry exists."; |
| 907 NavigationEntry* new_entry = new NavigationEntry( | 903 NavigationEntryImpl* new_entry = new NavigationEntryImpl( |
| 908 *NavigationEntry::FromNavigationEntry(GetLastCommittedEntry())); | 904 *NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry())); |
| 909 new_entry->SetPageID(params.page_id); | 905 new_entry->SetPageID(params.page_id); |
| 910 InsertOrReplaceEntry(new_entry, false); | 906 InsertOrReplaceEntry(new_entry, false); |
| 911 } | 907 } |
| 912 | 908 |
| 913 bool NavigationController::RendererDidNavigateAutoSubframe( | 909 bool NavigationController::RendererDidNavigateAutoSubframe( |
| 914 const ViewHostMsg_FrameNavigate_Params& params) { | 910 const ViewHostMsg_FrameNavigate_Params& params) { |
| 915 // We're guaranteed to have a previously committed entry, and we now need to | 911 // We're guaranteed to have a previously committed entry, and we now need to |
| 916 // handle navigation inside of a subframe in it without creating a new entry. | 912 // handle navigation inside of a subframe in it without creating a new entry. |
| 917 DCHECK(GetLastCommittedEntry()); | 913 DCHECK(GetLastCommittedEntry()); |
| 918 | 914 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 930 | 926 |
| 931 // Update the current navigation entry in case we're going back/forward. | 927 // Update the current navigation entry in case we're going back/forward. |
| 932 if (entry_index != last_committed_entry_index_) { | 928 if (entry_index != last_committed_entry_index_) { |
| 933 last_committed_entry_index_ = entry_index; | 929 last_committed_entry_index_ = entry_index; |
| 934 return true; | 930 return true; |
| 935 } | 931 } |
| 936 return false; | 932 return false; |
| 937 } | 933 } |
| 938 | 934 |
| 939 int NavigationController::GetIndexOfEntry( | 935 int NavigationController::GetIndexOfEntry( |
| 940 const NavigationEntry* entry) const { | 936 const NavigationEntryImpl* entry) const { |
| 941 const NavigationEntries::const_iterator i(std::find( | 937 const NavigationEntries::const_iterator i(std::find( |
| 942 entries_.begin(), | 938 entries_.begin(), |
| 943 entries_.end(), | 939 entries_.end(), |
| 944 entry)); | 940 entry)); |
| 945 return (i == entries_.end()) ? -1 : static_cast<int>(i - entries_.begin()); | 941 return (i == entries_.end()) ? -1 : static_cast<int>(i - entries_.begin()); |
| 946 } | 942 } |
| 947 | 943 |
| 948 bool NavigationController::IsURLInPageNavigation(const GURL& url) const { | 944 bool NavigationController::IsURLInPageNavigation(const GURL& url) const { |
| 949 content::NavigationEntry* last_committed = GetLastCommittedEntry(); | 945 NavigationEntry* last_committed = GetLastCommittedEntry(); |
| 950 if (!last_committed) | 946 if (!last_committed) |
| 951 return false; | 947 return false; |
| 952 return AreURLsInPageNavigation(last_committed->GetURL(), url); | 948 return AreURLsInPageNavigation(last_committed->GetURL(), url); |
| 953 } | 949 } |
| 954 | 950 |
| 955 void NavigationController::CopyStateFrom(const NavigationController& source) { | 951 void NavigationController::CopyStateFrom(const NavigationController& source) { |
| 956 // Verify that we look new. | 952 // Verify that we look new. |
| 957 DCHECK(entry_count() == 0 && !GetPendingEntry()); | 953 DCHECK(entry_count() == 0 && !GetPendingEntry()); |
| 958 | 954 |
| 959 if (source.entry_count() == 0) | 955 if (source.entry_count() == 0) |
| 960 return; // Nothing new to do. | 956 return; // Nothing new to do. |
| 961 | 957 |
| 962 needs_reload_ = true; | 958 needs_reload_ = true; |
| 963 InsertEntriesFrom(source, source.entry_count()); | 959 InsertEntriesFrom(source, source.entry_count()); |
| 964 | 960 |
| 965 session_storage_namespace_ = source.session_storage_namespace_->Clone(); | 961 session_storage_namespace_ = source.session_storage_namespace_->Clone(); |
| 966 | 962 |
| 967 FinishRestore(source.last_committed_entry_index_, false); | 963 FinishRestore(source.last_committed_entry_index_, false); |
| 968 } | 964 } |
| 969 | 965 |
| 970 void NavigationController::CopyStateFromAndPrune(NavigationController* source) { | 966 void NavigationController::CopyStateFromAndPrune(NavigationController* source) { |
| 971 // The SiteInstance and page_id of the last committed entry needs to be | 967 // The SiteInstance and page_id of the last committed entry needs to be |
| 972 // remembered at this point, in case there is only one committed entry | 968 // remembered at this point, in case there is only one committed entry |
| 973 // and it is pruned. | 969 // and it is pruned. |
| 974 NavigationEntry* last_committed = | 970 NavigationEntryImpl* last_committed = |
| 975 NavigationEntry::FromNavigationEntry(GetLastCommittedEntry()); | 971 NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry()); |
| 976 SiteInstance* site_instance = | 972 SiteInstance* site_instance = |
| 977 last_committed ? last_committed->site_instance() : NULL; | 973 last_committed ? last_committed->site_instance() : NULL; |
| 978 int32 minimum_page_id = last_committed ? last_committed->GetPageID() : -1; | 974 int32 minimum_page_id = last_committed ? last_committed->GetPageID() : -1; |
| 979 | 975 |
| 980 // This code is intended for use when the last entry is the active entry. | 976 // This code is intended for use when the last entry is the active entry. |
| 981 DCHECK((transient_entry_index_ != -1 && | 977 DCHECK((transient_entry_index_ != -1 && |
| 982 transient_entry_index_ == entry_count() - 1) || | 978 transient_entry_index_ == entry_count() - 1) || |
| 983 (pending_entry_ && (pending_entry_index_ == -1 || | 979 (pending_entry_ && (pending_entry_index_ == -1 || |
| 984 pending_entry_index_ == entry_count() - 1)) || | 980 pending_entry_index_ == entry_count() - 1)) || |
| 985 (!pending_entry_ && last_committed_entry_index_ == entry_count() - 1)); | 981 (!pending_entry_ && last_committed_entry_index_ == entry_count() - 1)); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1067 bool transient = transient_entry_index_ != -1; | 1063 bool transient = transient_entry_index_ != -1; |
| 1068 DiscardNonCommittedEntriesInternal(); | 1064 DiscardNonCommittedEntriesInternal(); |
| 1069 | 1065 |
| 1070 // If there was a transient entry, invalidate everything so the new active | 1066 // If there was a transient entry, invalidate everything so the new active |
| 1071 // entry state is shown. | 1067 // entry state is shown. |
| 1072 if (transient) { | 1068 if (transient) { |
| 1073 tab_contents_->NotifyNavigationStateChanged(kInvalidateAll); | 1069 tab_contents_->NotifyNavigationStateChanged(kInvalidateAll); |
| 1074 } | 1070 } |
| 1075 } | 1071 } |
| 1076 | 1072 |
| 1077 content::NavigationEntry* NavigationController::GetPendingEntry() const { | 1073 NavigationEntry* NavigationController::GetPendingEntry() const { |
| 1078 return pending_entry_; | 1074 return pending_entry_; |
| 1079 } | 1075 } |
| 1080 | 1076 |
| 1081 void NavigationController::InsertOrReplaceEntry(NavigationEntry* entry, | 1077 void NavigationController::InsertOrReplaceEntry(NavigationEntryImpl* entry, |
| 1082 bool replace) { | 1078 bool replace) { |
| 1083 DCHECK(entry->GetTransitionType() != content::PAGE_TRANSITION_AUTO_SUBFRAME); | 1079 DCHECK(entry->GetTransitionType() != content::PAGE_TRANSITION_AUTO_SUBFRAME); |
| 1084 | 1080 |
| 1085 // Copy the pending entry's unique ID to the committed entry. | 1081 // Copy the pending entry's unique ID to the committed entry. |
| 1086 // I don't know if pending_entry_index_ can be other than -1 here. | 1082 // I don't know if pending_entry_index_ can be other than -1 here. |
| 1087 const NavigationEntry* const pending_entry = (pending_entry_index_ == -1) ? | 1083 const NavigationEntryImpl* const pending_entry = |
| 1088 pending_entry_ : entries_[pending_entry_index_].get(); | 1084 (pending_entry_index_ == -1) ? |
| 1085 pending_entry_ : entries_[pending_entry_index_].get(); |
| 1089 if (pending_entry) | 1086 if (pending_entry) |
| 1090 entry->set_unique_id(pending_entry->GetUniqueID()); | 1087 entry->set_unique_id(pending_entry->GetUniqueID()); |
| 1091 | 1088 |
| 1092 DiscardNonCommittedEntriesInternal(); | 1089 DiscardNonCommittedEntriesInternal(); |
| 1093 | 1090 |
| 1094 int current_size = static_cast<int>(entries_.size()); | 1091 int current_size = static_cast<int>(entries_.size()); |
| 1095 | 1092 |
| 1096 if (current_size > 0) { | 1093 if (current_size > 0) { |
| 1097 // Prune any entries which are in front of the current entry. | 1094 // Prune any entries which are in front of the current entry. |
| 1098 // Also prune the current entry if we are to replace the current entry. | 1095 // Also prune the current entry if we are to replace the current entry. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1111 if (num_pruned > 0) // Only notify if we did prune something. | 1108 if (num_pruned > 0) // Only notify if we did prune something. |
| 1112 NotifyPrunedEntries(this, false, num_pruned); | 1109 NotifyPrunedEntries(this, false, num_pruned); |
| 1113 } | 1110 } |
| 1114 | 1111 |
| 1115 if (entries_.size() >= max_entry_count()) { | 1112 if (entries_.size() >= max_entry_count()) { |
| 1116 DCHECK(last_committed_entry_index_ > 0); | 1113 DCHECK(last_committed_entry_index_ > 0); |
| 1117 RemoveEntryAtIndex(0); | 1114 RemoveEntryAtIndex(0); |
| 1118 NotifyPrunedEntries(this, true, 1); | 1115 NotifyPrunedEntries(this, true, 1); |
| 1119 } | 1116 } |
| 1120 | 1117 |
| 1121 entries_.push_back(linked_ptr<NavigationEntry>(entry)); | 1118 entries_.push_back(linked_ptr<NavigationEntryImpl>(entry)); |
| 1122 last_committed_entry_index_ = static_cast<int>(entries_.size()) - 1; | 1119 last_committed_entry_index_ = static_cast<int>(entries_.size()) - 1; |
| 1123 | 1120 |
| 1124 // This is a new page ID, so we need everybody to know about it. | 1121 // This is a new page ID, so we need everybody to know about it. |
| 1125 tab_contents_->UpdateMaxPageID(entry->GetPageID()); | 1122 tab_contents_->UpdateMaxPageID(entry->GetPageID()); |
| 1126 } | 1123 } |
| 1127 | 1124 |
| 1128 void NavigationController::NavigateToPendingEntry(ReloadType reload_type) { | 1125 void NavigationController::NavigateToPendingEntry(ReloadType reload_type) { |
| 1129 needs_reload_ = false; | 1126 needs_reload_ = false; |
| 1130 | 1127 |
| 1131 // If we were navigating to a slow-to-commit page, and the user performs | 1128 // If we were navigating to a slow-to-commit page, and the user performs |
| 1132 // a session history navigation to the last committed page, RenderViewHost | 1129 // a session history navigation to the last committed page, RenderViewHost |
| 1133 // will force the throbber to start, but WebKit will essentially ignore the | 1130 // will force the throbber to start, but WebKit will essentially ignore the |
| 1134 // navigation, and won't send a message to stop the throbber. To prevent this | 1131 // navigation, and won't send a message to stop the throbber. To prevent this |
| 1135 // from happening, we drop the navigation here and stop the slow-to-commit | 1132 // from happening, we drop the navigation here and stop the slow-to-commit |
| 1136 // page from loading (which would normally happen during the navigation). | 1133 // page from loading (which would normally happen during the navigation). |
| 1137 if (pending_entry_index_ != -1 && | 1134 if (pending_entry_index_ != -1 && |
| 1138 pending_entry_index_ == last_committed_entry_index_ && | 1135 pending_entry_index_ == last_committed_entry_index_ && |
| 1139 (entries_[pending_entry_index_]->restore_type() == | 1136 (entries_[pending_entry_index_]->restore_type() == |
| 1140 NavigationEntry::RESTORE_NONE) && | 1137 NavigationEntryImpl::RESTORE_NONE) && |
| 1141 (entries_[pending_entry_index_]->GetTransitionType() & | 1138 (entries_[pending_entry_index_]->GetTransitionType() & |
| 1142 content::PAGE_TRANSITION_FORWARD_BACK)) { | 1139 content::PAGE_TRANSITION_FORWARD_BACK)) { |
| 1143 tab_contents_->Stop(); | 1140 tab_contents_->Stop(); |
| 1144 | 1141 |
| 1145 // If an interstitial page is showing, we want to close it to get back | 1142 // If an interstitial page is showing, we want to close it to get back |
| 1146 // to what was showing before. | 1143 // to what was showing before. |
| 1147 if (tab_contents_->GetInterstitialPage()) | 1144 if (tab_contents_->GetInterstitialPage()) |
| 1148 tab_contents_->GetInterstitialPage()->DontProceed(); | 1145 tab_contents_->GetInterstitialPage()->DontProceed(); |
| 1149 | 1146 |
| 1150 DiscardNonCommittedEntries(); | 1147 DiscardNonCommittedEntries(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1165 } | 1162 } |
| 1166 | 1163 |
| 1167 if (!tab_contents_->NavigateToPendingEntry(reload_type)) | 1164 if (!tab_contents_->NavigateToPendingEntry(reload_type)) |
| 1168 DiscardNonCommittedEntries(); | 1165 DiscardNonCommittedEntries(); |
| 1169 | 1166 |
| 1170 // If the entry is being restored and doesn't have a SiteInstance yet, fill | 1167 // If the entry is being restored and doesn't have a SiteInstance yet, fill |
| 1171 // it in now that we know. This allows us to find the entry when it commits. | 1168 // it in now that we know. This allows us to find the entry when it commits. |
| 1172 // This works for browser-initiated navigations. We handle renderer-initiated | 1169 // This works for browser-initiated navigations. We handle renderer-initiated |
| 1173 // navigations to restored entries in TabContents::OnGoToEntryAtOffset. | 1170 // navigations to restored entries in TabContents::OnGoToEntryAtOffset. |
| 1174 if (pending_entry_ && !pending_entry_->site_instance() && | 1171 if (pending_entry_ && !pending_entry_->site_instance() && |
| 1175 pending_entry_->restore_type() != NavigationEntry::RESTORE_NONE) { | 1172 pending_entry_->restore_type() != NavigationEntryImpl::RESTORE_NONE) { |
| 1176 pending_entry_->set_site_instance(tab_contents_->GetPendingSiteInstance()); | 1173 pending_entry_->set_site_instance(tab_contents_->GetPendingSiteInstance()); |
| 1177 pending_entry_->set_restore_type(NavigationEntry::RESTORE_NONE); | 1174 pending_entry_->set_restore_type(NavigationEntryImpl::RESTORE_NONE); |
| 1178 } | 1175 } |
| 1179 } | 1176 } |
| 1180 | 1177 |
| 1181 void NavigationController::NotifyNavigationEntryCommitted( | 1178 void NavigationController::NotifyNavigationEntryCommitted( |
| 1182 content::LoadCommittedDetails* details) { | 1179 content::LoadCommittedDetails* details) { |
| 1183 details->entry = GetActiveEntry(); | 1180 details->entry = GetActiveEntry(); |
| 1184 content::NotificationDetails notification_details = | 1181 content::NotificationDetails notification_details = |
| 1185 content::Details<content::LoadCommittedDetails>(details); | 1182 content::Details<content::LoadCommittedDetails>(details); |
| 1186 | 1183 |
| 1187 // We need to notify the ssl_manager_ before the tab_contents_ so the | 1184 // We need to notify the ssl_manager_ before the tab_contents_ so the |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1221 if (!needs_reload_) | 1218 if (!needs_reload_) |
| 1222 return; | 1219 return; |
| 1223 | 1220 |
| 1224 // Calling Reload() results in ignoring state, and not loading. | 1221 // Calling Reload() results in ignoring state, and not loading. |
| 1225 // Explicitly use NavigateToPendingEntry so that the renderer uses the | 1222 // Explicitly use NavigateToPendingEntry so that the renderer uses the |
| 1226 // cached state. | 1223 // cached state. |
| 1227 pending_entry_index_ = last_committed_entry_index_; | 1224 pending_entry_index_ = last_committed_entry_index_; |
| 1228 NavigateToPendingEntry(NO_RELOAD); | 1225 NavigateToPendingEntry(NO_RELOAD); |
| 1229 } | 1226 } |
| 1230 | 1227 |
| 1231 void NavigationController::NotifyEntryChanged( | 1228 void NavigationController::NotifyEntryChanged(const NavigationEntry* entry, |
| 1232 const content::NavigationEntry* entry, int index) { | 1229 int index) { |
| 1233 content::EntryChangedDetails det; | 1230 content::EntryChangedDetails det; |
| 1234 det.changed_entry = entry; | 1231 det.changed_entry = entry; |
| 1235 det.index = index; | 1232 det.index = index; |
| 1236 content::NotificationService::current()->Notify( | 1233 content::NotificationService::current()->Notify( |
| 1237 content::NOTIFICATION_NAV_ENTRY_CHANGED, | 1234 content::NOTIFICATION_NAV_ENTRY_CHANGED, |
| 1238 content::Source<NavigationController>(this), | 1235 content::Source<NavigationController>(this), |
| 1239 content::Details<content::EntryChangedDetails>(&det)); | 1236 content::Details<content::EntryChangedDetails>(&det)); |
| 1240 } | 1237 } |
| 1241 | 1238 |
| 1242 void NavigationController::FinishRestore(int selected_index, | 1239 void NavigationController::FinishRestore(int selected_index, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1270 int NavigationController::GetEntryIndexWithPageID( | 1267 int NavigationController::GetEntryIndexWithPageID( |
| 1271 SiteInstance* instance, int32 page_id) const { | 1268 SiteInstance* instance, int32 page_id) const { |
| 1272 for (int i = static_cast<int>(entries_.size()) - 1; i >= 0; --i) { | 1269 for (int i = static_cast<int>(entries_.size()) - 1; i >= 0; --i) { |
| 1273 if ((entries_[i]->site_instance() == instance) && | 1270 if ((entries_[i]->site_instance() == instance) && |
| 1274 (entries_[i]->GetPageID() == page_id)) | 1271 (entries_[i]->GetPageID() == page_id)) |
| 1275 return i; | 1272 return i; |
| 1276 } | 1273 } |
| 1277 return -1; | 1274 return -1; |
| 1278 } | 1275 } |
| 1279 | 1276 |
| 1280 content::NavigationEntry* NavigationController::GetTransientEntry() const { | 1277 NavigationEntry* NavigationController::GetTransientEntry() const { |
| 1281 if (transient_entry_index_ == -1) | 1278 if (transient_entry_index_ == -1) |
| 1282 return NULL; | 1279 return NULL; |
| 1283 return entries_[transient_entry_index_].get(); | 1280 return entries_[transient_entry_index_].get(); |
| 1284 } | 1281 } |
| 1285 | 1282 |
| 1286 void NavigationController::InsertEntriesFrom( | 1283 void NavigationController::InsertEntriesFrom( |
| 1287 const NavigationController& source, | 1284 const NavigationController& source, |
| 1288 int max_index) { | 1285 int max_index) { |
| 1289 DCHECK_LE(max_index, source.entry_count()); | 1286 DCHECK_LE(max_index, source.entry_count()); |
| 1290 size_t insert_index = 0; | 1287 size_t insert_index = 0; |
| 1291 for (int i = 0; i < max_index; i++) { | 1288 for (int i = 0; i < max_index; i++) { |
| 1292 // When cloning a tab, copy all entries except interstitial pages | 1289 // When cloning a tab, copy all entries except interstitial pages |
| 1293 if (source.entries_[i].get()->GetPageType() != | 1290 if (source.entries_[i].get()->GetPageType() != |
| 1294 content::PAGE_TYPE_INTERSTITIAL) { | 1291 content::PAGE_TYPE_INTERSTITIAL) { |
| 1295 entries_.insert(entries_.begin() + insert_index++, | 1292 entries_.insert(entries_.begin() + insert_index++, |
| 1296 linked_ptr<NavigationEntry>( | 1293 linked_ptr<NavigationEntryImpl>( |
| 1297 new NavigationEntry(*source.entries_[i]))); | 1294 new NavigationEntryImpl(*source.entries_[i]))); |
| 1298 } | 1295 } |
| 1299 } | 1296 } |
| 1300 } | 1297 } |
| OLD | NEW |