| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "chrome/browser/tab_contents/navigation_controller.h" | 5 #include "chrome/browser/tab_contents/navigation_controller.h" |
| 6 | 6 |
| 7 #include "app/resource_bundle.h" | 7 #include "app/resource_bundle.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 bool AreURLsInPageNavigation(const GURL& existing_url, const GURL& new_url) { | 83 bool AreURLsInPageNavigation(const GURL& existing_url, const GURL& new_url) { |
| 84 if (existing_url == new_url || !new_url.has_ref()) | 84 if (existing_url == new_url || !new_url.has_ref()) |
| 85 return false; | 85 return false; |
| 86 | 86 |
| 87 url_canon::Replacements<char> replacements; | 87 url_canon::Replacements<char> replacements; |
| 88 replacements.ClearRef(); | 88 replacements.ClearRef(); |
| 89 return existing_url.ReplaceComponents(replacements) == | 89 return existing_url.ReplaceComponents(replacements) == |
| 90 new_url.ReplaceComponents(replacements); | 90 new_url.ReplaceComponents(replacements); |
| 91 } | 91 } |
| 92 | 92 |
| 93 // Navigation within this limit since the last document load is considered to | |
| 94 // be automatic (i.e., machine-initiated) rather than user-initiated unless | |
| 95 // a user gesture has been observed. | |
| 96 const base::TimeDelta kMaxAutoNavigationTimeDelta = | |
| 97 base::TimeDelta::FromSeconds(5); | |
| 98 | |
| 99 } // namespace | 93 } // namespace |
| 100 | 94 |
| 101 // NavigationController --------------------------------------------------- | 95 // NavigationController --------------------------------------------------- |
| 102 | 96 |
| 103 // static | 97 // static |
| 104 size_t NavigationController::max_entry_count_ = 50; | 98 size_t NavigationController::max_entry_count_ = 50; |
| 105 | 99 |
| 106 // static | 100 // static |
| 107 bool NavigationController::check_for_repost_ = true; | 101 bool NavigationController::check_for_repost_ = true; |
| 108 | 102 |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 | 417 |
| 424 const SkBitmap& NavigationController::GetLazyFavIcon() const { | 418 const SkBitmap& NavigationController::GetLazyFavIcon() const { |
| 425 if (pending_entry_) { | 419 if (pending_entry_) { |
| 426 return pending_entry_->favicon().bitmap(); | 420 return pending_entry_->favicon().bitmap(); |
| 427 } else { | 421 } else { |
| 428 ResourceBundle &rb = ResourceBundle::GetSharedInstance(); | 422 ResourceBundle &rb = ResourceBundle::GetSharedInstance(); |
| 429 return *rb.GetBitmapNamed(IDR_DEFAULT_FAVICON); | 423 return *rb.GetBitmapNamed(IDR_DEFAULT_FAVICON); |
| 430 } | 424 } |
| 431 } | 425 } |
| 432 | 426 |
| 433 void NavigationController::DocumentLoadedInFrame() { | |
| 434 last_document_loaded_ = base::TimeTicks::Now(); | |
| 435 } | |
| 436 | |
| 437 void NavigationController::OnUserGesture() { | |
| 438 user_gesture_observed_ = true; | |
| 439 } | |
| 440 | |
| 441 bool NavigationController::RendererDidNavigate( | 427 bool NavigationController::RendererDidNavigate( |
| 442 const ViewHostMsg_FrameNavigate_Params& params, | 428 const ViewHostMsg_FrameNavigate_Params& params, |
| 443 LoadCommittedDetails* details) { | 429 LoadCommittedDetails* details) { |
| 444 // Save the previous state before we clobber it. | 430 // Save the previous state before we clobber it. |
| 445 if (GetLastCommittedEntry()) { | 431 if (GetLastCommittedEntry()) { |
| 446 details->previous_url = GetLastCommittedEntry()->url(); | 432 details->previous_url = GetLastCommittedEntry()->url(); |
| 447 details->previous_entry_index = last_committed_entry_index(); | 433 details->previous_entry_index = last_committed_entry_index(); |
| 448 } else { | 434 } else { |
| 449 details->previous_url = GURL(); | 435 details->previous_url = GURL(); |
| 450 details->previous_entry_index = -1; | 436 details->previous_entry_index = -1; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 | 498 |
| 513 // Now prep the rest of the details for the notification and broadcast. | 499 // Now prep the rest of the details for the notification and broadcast. |
| 514 details->entry = GetActiveEntry(); | 500 details->entry = GetActiveEntry(); |
| 515 details->is_in_page = IsURLInPageNavigation(params.url); | 501 details->is_in_page = IsURLInPageNavigation(params.url); |
| 516 details->is_main_frame = PageTransition::IsMainFrame(params.transition); | 502 details->is_main_frame = PageTransition::IsMainFrame(params.transition); |
| 517 details->serialized_security_info = params.security_info; | 503 details->serialized_security_info = params.security_info; |
| 518 details->is_content_filtered = params.is_content_filtered; | 504 details->is_content_filtered = params.is_content_filtered; |
| 519 details->http_status_code = params.http_status_code; | 505 details->http_status_code = params.http_status_code; |
| 520 NotifyNavigationEntryCommitted(details); | 506 NotifyNavigationEntryCommitted(details); |
| 521 | 507 |
| 522 user_gesture_observed_ = false; | |
| 523 | |
| 524 return true; | 508 return true; |
| 525 } | 509 } |
| 526 | 510 |
| 527 NavigationType::Type NavigationController::ClassifyNavigation( | 511 NavigationType::Type NavigationController::ClassifyNavigation( |
| 528 const ViewHostMsg_FrameNavigate_Params& params) const { | 512 const ViewHostMsg_FrameNavigate_Params& params) const { |
| 529 // If a page makes a popup navigated to about blank, and then writes stuff | 513 // If a page makes a popup navigated to about blank, and then writes stuff |
| 530 // like a subframe navigated to a real site, we'll get a notification with an | 514 // like a subframe navigated to a real site, we'll get a notification with an |
| 531 // invalid page ID. There's nothing we can do with these, so just ignore them. | 515 // invalid page ID. There's nothing we can do with these, so just ignore them. |
| 532 if (params.page_id == -1) { | 516 if (params.page_id == -1) { |
| 533 DCHECK(!GetActiveEntry()) << "Got an invalid page ID but we seem to be " | 517 DCHECK(!GetActiveEntry()) << "Got an invalid page ID but we seem to be " |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 // navigations that don't actually navigate, but it can happen when there is | 578 // navigations that don't actually navigate, but it can happen when there is |
| 595 // an encoding override (it always sends a navigation request). | 579 // an encoding override (it always sends a navigation request). |
| 596 if (AreURLsInPageNavigation(existing_entry->url(), params.url)) | 580 if (AreURLsInPageNavigation(existing_entry->url(), params.url)) |
| 597 return NavigationType::IN_PAGE; | 581 return NavigationType::IN_PAGE; |
| 598 | 582 |
| 599 // Since we weeded out "new" navigations above, we know this is an existing | 583 // Since we weeded out "new" navigations above, we know this is an existing |
| 600 // (back/forward) navigation. | 584 // (back/forward) navigation. |
| 601 return NavigationType::EXISTING_PAGE; | 585 return NavigationType::EXISTING_PAGE; |
| 602 } | 586 } |
| 603 | 587 |
| 604 bool NavigationController::IsRedirect( | |
| 605 const ViewHostMsg_FrameNavigate_Params& params) { | |
| 606 // For main frame transition, we judge by params.transition. | |
| 607 // Otherwise, by params.redirects. | |
| 608 if (PageTransition::IsMainFrame(params.transition)) { | |
| 609 return PageTransition::IsRedirect(params.transition); | |
| 610 } | |
| 611 return params.redirects.size() > 1; | |
| 612 } | |
| 613 | |
| 614 bool NavigationController::IsLikelyAutoNavigation(base::TimeTicks now) { | |
| 615 return !user_gesture_observed_ && | |
| 616 (now - last_document_loaded_) < kMaxAutoNavigationTimeDelta; | |
| 617 } | |
| 618 | |
| 619 void NavigationController::RendererDidNavigateToNewPage( | 588 void NavigationController::RendererDidNavigateToNewPage( |
| 620 const ViewHostMsg_FrameNavigate_Params& params) { | 589 const ViewHostMsg_FrameNavigate_Params& params) { |
| 621 NavigationEntry* new_entry; | 590 NavigationEntry* new_entry; |
| 622 if (pending_entry_) { | 591 if (pending_entry_) { |
| 623 // TODO(brettw) this assumes that the pending entry is appropriate for the | 592 // TODO(brettw) this assumes that the pending entry is appropriate for the |
| 624 // new page that was just loaded. I don't think this is necessarily the | 593 // new page that was just loaded. I don't think this is necessarily the |
| 625 // case! We should have some more tracking to know for sure. This goes along | 594 // case! We should have some more tracking to know for sure. This goes along |
| 626 // with a similar TODO at the top of RendererDidNavigate where we blindly | 595 // with a similar TODO at the top of RendererDidNavigate where we blindly |
| 627 // set the site instance on the pending entry. | 596 // set the site instance on the pending entry. |
| 628 new_entry = new NavigationEntry(*pending_entry_); | 597 new_entry = new NavigationEntry(*pending_entry_); |
| 629 | 598 |
| 630 // Don't use the page type from the pending entry. Some interstitial page | 599 // Don't use the page type from the pending entry. Some interstitial page |
| 631 // may have set the type to interstitial. Once we commit, however, the page | 600 // may have set the type to interstitial. Once we commit, however, the page |
| 632 // type must always be normal. | 601 // type must always be normal. |
| 633 new_entry->set_page_type(NavigationEntry::NORMAL_PAGE); | 602 new_entry->set_page_type(NavigationEntry::NORMAL_PAGE); |
| 634 } else { | 603 } else { |
| 635 new_entry = new NavigationEntry; | 604 new_entry = new NavigationEntry; |
| 636 } | 605 } |
| 637 | 606 |
| 638 new_entry->set_url(params.url); | 607 new_entry->set_url(params.url); |
| 639 new_entry->set_referrer(params.referrer); | 608 new_entry->set_referrer(params.referrer); |
| 640 new_entry->set_page_id(params.page_id); | 609 new_entry->set_page_id(params.page_id); |
| 641 new_entry->set_transition_type(params.transition); | 610 new_entry->set_transition_type(params.transition); |
| 642 new_entry->set_site_instance(tab_contents_->GetSiteInstance()); | 611 new_entry->set_site_instance(tab_contents_->GetSiteInstance()); |
| 643 new_entry->set_has_post_data(params.is_post); | 612 new_entry->set_has_post_data(params.is_post); |
| 644 | 613 |
| 645 // If the current entry is a redirection source and the redirection has | 614 // If the current entry is a redirection source, it needs to be replaced with |
| 646 // occurred within kMaxAutoNavigationTimeDelta since the last document load, | 615 // the new entry to avoid unwanted redirections in navigating backward / |
| 647 // this is likely to be machine-initiated redirect and the entry needs to be | 616 // forward. Otherwise, just insert the new entry. |
| 648 // replaced with the new entry to avoid unwanted redirections in navigating | |
| 649 // backward/forward. | |
| 650 // Otherwise, just insert the new entry. | |
| 651 InsertOrReplaceEntry(new_entry, | 617 InsertOrReplaceEntry(new_entry, |
| 652 IsRedirect(params) && IsLikelyAutoNavigation(base::TimeTicks::Now())); | 618 PageTransition::IsRedirect(new_entry->transition_type())); |
| 653 } | 619 } |
| 654 | 620 |
| 655 void NavigationController::RendererDidNavigateToExistingPage( | 621 void NavigationController::RendererDidNavigateToExistingPage( |
| 656 const ViewHostMsg_FrameNavigate_Params& params) { | 622 const ViewHostMsg_FrameNavigate_Params& params) { |
| 657 // We should only get here for main frame navigations. | 623 // We should only get here for main frame navigations. |
| 658 DCHECK(PageTransition::IsMainFrame(params.transition)); | 624 DCHECK(PageTransition::IsMainFrame(params.transition)); |
| 659 | 625 |
| 660 // This is a back/forward navigation. The existing page for the ID is | 626 // This is a back/forward navigation. The existing page for the ID is |
| 661 // guaranteed to exist by ClassifyNavigation, and we just need to update it | 627 // guaranteed to exist by ClassifyNavigation, and we just need to update it |
| 662 // with new information from the renderer. | 628 // with new information from the renderer. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 NavigationEntry* existing_entry = GetEntryWithPageID( | 680 NavigationEntry* existing_entry = GetEntryWithPageID( |
| 715 tab_contents_->GetSiteInstance(), | 681 tab_contents_->GetSiteInstance(), |
| 716 params.page_id); | 682 params.page_id); |
| 717 | 683 |
| 718 // Reference fragment navigation. We're guaranteed to have the last_committed | 684 // Reference fragment navigation. We're guaranteed to have the last_committed |
| 719 // entry and it will be the same page as the new navigation (minus the | 685 // entry and it will be the same page as the new navigation (minus the |
| 720 // reference fragments, of course). | 686 // reference fragments, of course). |
| 721 NavigationEntry* new_entry = new NavigationEntry(*existing_entry); | 687 NavigationEntry* new_entry = new NavigationEntry(*existing_entry); |
| 722 new_entry->set_page_id(params.page_id); | 688 new_entry->set_page_id(params.page_id); |
| 723 new_entry->set_url(params.url); | 689 new_entry->set_url(params.url); |
| 724 InsertOrReplaceEntry(new_entry, | 690 InsertOrReplaceEntry(new_entry, false); |
| 725 IsRedirect(params) && IsLikelyAutoNavigation(base::TimeTicks::Now())); | |
| 726 } | 691 } |
| 727 | 692 |
| 728 void NavigationController::RendererDidNavigateNewSubframe( | 693 void NavigationController::RendererDidNavigateNewSubframe( |
| 729 const ViewHostMsg_FrameNavigate_Params& params) { | 694 const ViewHostMsg_FrameNavigate_Params& params) { |
| 730 if (PageTransition::StripQualifier(params.transition) == | |
| 731 PageTransition::AUTO_SUBFRAME) { | |
| 732 // This is not user-initiated. Ignore. | |
| 733 return; | |
| 734 } | |
| 735 if (IsRedirect(params)) { | |
| 736 // This is redirect. Ignore. | |
| 737 return; | |
| 738 } | |
| 739 | |
| 740 // Manual subframe navigations just get the current entry cloned so the user | 695 // Manual subframe navigations just get the current entry cloned so the user |
| 741 // can go back or forward to it. The actual subframe information will be | 696 // can go back or forward to it. The actual subframe information will be |
| 742 // stored in the page state for each of those entries. This happens out of | 697 // stored in the page state for each of those entries. This happens out of |
| 743 // band with the actual navigations. | 698 // band with the actual navigations. |
| 744 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " | 699 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " |
| 745 << "that a last committed entry exists."; | 700 << "that a last committed entry exists."; |
| 746 NavigationEntry* new_entry = new NavigationEntry(*GetLastCommittedEntry()); | 701 NavigationEntry* new_entry = new NavigationEntry(*GetLastCommittedEntry()); |
| 747 new_entry->set_page_id(params.page_id); | 702 new_entry->set_page_id(params.page_id); |
| 748 InsertOrReplaceEntry(new_entry, false); | 703 InsertOrReplaceEntry(new_entry, false); |
| 749 } | 704 } |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 return i; | 974 return i; |
| 1020 } | 975 } |
| 1021 return -1; | 976 return -1; |
| 1022 } | 977 } |
| 1023 | 978 |
| 1024 NavigationEntry* NavigationController::GetTransientEntry() const { | 979 NavigationEntry* NavigationController::GetTransientEntry() const { |
| 1025 if (transient_entry_index_ == -1) | 980 if (transient_entry_index_ == -1) |
| 1026 return NULL; | 981 return NULL; |
| 1027 return entries_[transient_entry_index_].get(); | 982 return entries_[transient_entry_index_].get(); |
| 1028 } | 983 } |
| OLD | NEW |