| 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 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 new_entry = new NavigationEntry; | 598 new_entry = new NavigationEntry; |
| 599 } | 599 } |
| 600 | 600 |
| 601 new_entry->set_url(params.url); | 601 new_entry->set_url(params.url); |
| 602 new_entry->set_referrer(params.referrer); | 602 new_entry->set_referrer(params.referrer); |
| 603 new_entry->set_page_id(params.page_id); | 603 new_entry->set_page_id(params.page_id); |
| 604 new_entry->set_transition_type(params.transition); | 604 new_entry->set_transition_type(params.transition); |
| 605 new_entry->set_site_instance(tab_contents_->GetSiteInstance()); | 605 new_entry->set_site_instance(tab_contents_->GetSiteInstance()); |
| 606 new_entry->set_has_post_data(params.is_post); | 606 new_entry->set_has_post_data(params.is_post); |
| 607 | 607 |
| 608 InsertEntry(new_entry); | 608 // If the current entry is a redirection source, it needs to be replaced with |
| 609 // the new entry to avoid unwanted redirections in navigating backward / |
| 610 // forward. Otherwise, just insert the new entry. |
| 611 InsertOrReplaceEntry(new_entry, |
| 612 PageTransition::IsRedirect(new_entry->transition_type())); |
| 609 } | 613 } |
| 610 | 614 |
| 611 void NavigationController::RendererDidNavigateToExistingPage( | 615 void NavigationController::RendererDidNavigateToExistingPage( |
| 612 const ViewHostMsg_FrameNavigate_Params& params) { | 616 const ViewHostMsg_FrameNavigate_Params& params) { |
| 613 // We should only get here for main frame navigations. | 617 // We should only get here for main frame navigations. |
| 614 DCHECK(PageTransition::IsMainFrame(params.transition)); | 618 DCHECK(PageTransition::IsMainFrame(params.transition)); |
| 615 | 619 |
| 616 // This is a back/forward navigation. The existing page for the ID is | 620 // This is a back/forward navigation. The existing page for the ID is |
| 617 // guaranteed to exist by ClassifyNavigation, and we just need to update it | 621 // guaranteed to exist by ClassifyNavigation, and we just need to update it |
| 618 // with new information from the renderer. | 622 // with new information from the renderer. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 667 NavigationEntry* existing_entry = GetEntryWithPageID( | 671 NavigationEntry* existing_entry = GetEntryWithPageID( |
| 668 tab_contents_->GetSiteInstance(), | 672 tab_contents_->GetSiteInstance(), |
| 669 params.page_id); | 673 params.page_id); |
| 670 | 674 |
| 671 // Reference fragment navigation. We're guaranteed to have the last_committed | 675 // Reference fragment navigation. We're guaranteed to have the last_committed |
| 672 // entry and it will be the same page as the new navigation (minus the | 676 // entry and it will be the same page as the new navigation (minus the |
| 673 // reference fragments, of course). | 677 // reference fragments, of course). |
| 674 NavigationEntry* new_entry = new NavigationEntry(*existing_entry); | 678 NavigationEntry* new_entry = new NavigationEntry(*existing_entry); |
| 675 new_entry->set_page_id(params.page_id); | 679 new_entry->set_page_id(params.page_id); |
| 676 new_entry->set_url(params.url); | 680 new_entry->set_url(params.url); |
| 677 InsertEntry(new_entry); | 681 InsertOrReplaceEntry(new_entry, false); |
| 678 } | 682 } |
| 679 | 683 |
| 680 void NavigationController::RendererDidNavigateNewSubframe( | 684 void NavigationController::RendererDidNavigateNewSubframe( |
| 681 const ViewHostMsg_FrameNavigate_Params& params) { | 685 const ViewHostMsg_FrameNavigate_Params& params) { |
| 682 // Manual subframe navigations just get the current entry cloned so the user | 686 // Manual subframe navigations just get the current entry cloned so the user |
| 683 // can go back or forward to it. The actual subframe information will be | 687 // can go back or forward to it. The actual subframe information will be |
| 684 // stored in the page state for each of those entries. This happens out of | 688 // stored in the page state for each of those entries. This happens out of |
| 685 // band with the actual navigations. | 689 // band with the actual navigations. |
| 686 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " | 690 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " |
| 687 << "that a last committed entry exists."; | 691 << "that a last committed entry exists."; |
| 688 NavigationEntry* new_entry = new NavigationEntry(*GetLastCommittedEntry()); | 692 NavigationEntry* new_entry = new NavigationEntry(*GetLastCommittedEntry()); |
| 689 new_entry->set_page_id(params.page_id); | 693 new_entry->set_page_id(params.page_id); |
| 690 InsertEntry(new_entry); | 694 InsertOrReplaceEntry(new_entry, false); |
| 691 } | 695 } |
| 692 | 696 |
| 693 bool NavigationController::RendererDidNavigateAutoSubframe( | 697 bool NavigationController::RendererDidNavigateAutoSubframe( |
| 694 const ViewHostMsg_FrameNavigate_Params& params) { | 698 const ViewHostMsg_FrameNavigate_Params& params) { |
| 695 // We're guaranteed to have a previously committed entry, and we now need to | 699 // We're guaranteed to have a previously committed entry, and we now need to |
| 696 // handle navigation inside of a subframe in it without creating a new entry. | 700 // handle navigation inside of a subframe in it without creating a new entry. |
| 697 DCHECK(GetLastCommittedEntry()); | 701 DCHECK(GetLastCommittedEntry()); |
| 698 | 702 |
| 699 // Handle the case where we're navigating back/forward to a previous subframe | 703 // Handle the case where we're navigating back/forward to a previous subframe |
| 700 // navigation entry. This is case "2." in NAV_AUTO_SUBFRAME comment in the | 704 // navigation entry. This is case "2." in NAV_AUTO_SUBFRAME comment in the |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 736 // This is a previous navigation (back/forward) that we're just now | 740 // This is a previous navigation (back/forward) that we're just now |
| 737 // committing. Just mark it as committed. | 741 // committing. Just mark it as committed. |
| 738 details.type = NavigationType::EXISTING_PAGE; | 742 details.type = NavigationType::EXISTING_PAGE; |
| 739 int new_entry_index = pending_entry_index_; | 743 int new_entry_index = pending_entry_index_; |
| 740 DiscardNonCommittedEntriesInternal(); | 744 DiscardNonCommittedEntriesInternal(); |
| 741 | 745 |
| 742 // Mark that entry as committed. | 746 // Mark that entry as committed. |
| 743 last_committed_entry_index_ = new_entry_index; | 747 last_committed_entry_index_ = new_entry_index; |
| 744 } else { | 748 } else { |
| 745 // This is a new navigation. It's easiest to just copy the entry and insert | 749 // This is a new navigation. It's easiest to just copy the entry and insert |
| 746 // it new again, since InsertEntry expects to take ownership and also | 750 // it new again, since InsertOrReplaceEntry expects to take ownership and |
| 747 // discard the pending entry. We also need to synthesize a page ID. We can | 751 // also discard the pending entry. We also need to synthesize a page ID. We |
| 748 // only do this because this function will only be called by our custom | 752 // can only do this because this function will only be called by our custom |
| 749 // TabContents types. For TabContents, the IDs are generated by the | 753 // TabContents types. For TabContents, the IDs are generated by the |
| 750 // renderer, so we can't do this. | 754 // renderer, so we can't do this. |
| 751 details.type = NavigationType::NEW_PAGE; | 755 details.type = NavigationType::NEW_PAGE; |
| 752 pending_entry_->set_page_id(tab_contents_->GetMaxPageID() + 1); | 756 pending_entry_->set_page_id(tab_contents_->GetMaxPageID() + 1); |
| 753 tab_contents_->UpdateMaxPageID(pending_entry_->page_id()); | 757 tab_contents_->UpdateMaxPageID(pending_entry_->page_id()); |
| 754 InsertEntry(new NavigationEntry(*pending_entry_)); | 758 InsertOrReplaceEntry(new NavigationEntry(*pending_entry_), false); |
| 755 } | 759 } |
| 756 | 760 |
| 757 // Broadcast the notification of the navigation. | 761 // Broadcast the notification of the navigation. |
| 758 details.entry = GetActiveEntry(); | 762 details.entry = GetActiveEntry(); |
| 759 details.is_auto = false; | 763 details.is_auto = false; |
| 760 details.is_in_page = AreURLsInPageNavigation(details.previous_url, | 764 details.is_in_page = AreURLsInPageNavigation(details.previous_url, |
| 761 details.entry->url()); | 765 details.entry->url()); |
| 762 details.is_main_frame = true; | 766 details.is_main_frame = true; |
| 763 NotifyNavigationEntryCommitted(&details); | 767 NotifyNavigationEntryCommitted(&details); |
| 764 } | 768 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 800 DiscardNonCommittedEntriesInternal(); | 804 DiscardNonCommittedEntriesInternal(); |
| 801 | 805 |
| 802 // If there was a transient entry, invalidate everything so the new active | 806 // If there was a transient entry, invalidate everything so the new active |
| 803 // entry state is shown. | 807 // entry state is shown. |
| 804 if (transient) { | 808 if (transient) { |
| 805 tab_contents_->NotifyNavigationStateChanged( | 809 tab_contents_->NotifyNavigationStateChanged( |
| 806 TabContents::INVALIDATE_EVERYTHING); | 810 TabContents::INVALIDATE_EVERYTHING); |
| 807 } | 811 } |
| 808 } | 812 } |
| 809 | 813 |
| 810 void NavigationController::InsertEntry(NavigationEntry* entry) { | 814 void NavigationController::InsertOrReplaceEntry(NavigationEntry* entry, |
| 815 bool replace) { |
| 811 DCHECK(entry->transition_type() != PageTransition::AUTO_SUBFRAME); | 816 DCHECK(entry->transition_type() != PageTransition::AUTO_SUBFRAME); |
| 812 | 817 |
| 813 // Copy the pending entry's unique ID to the committed entry. | 818 // Copy the pending entry's unique ID to the committed entry. |
| 814 // I don't know if pending_entry_index_ can be other than -1 here. | 819 // I don't know if pending_entry_index_ can be other than -1 here. |
| 815 const NavigationEntry* const pending_entry = (pending_entry_index_ == -1) ? | 820 const NavigationEntry* const pending_entry = (pending_entry_index_ == -1) ? |
| 816 pending_entry_ : entries_[pending_entry_index_].get(); | 821 pending_entry_ : entries_[pending_entry_index_].get(); |
| 817 if (pending_entry) | 822 if (pending_entry) |
| 818 entry->set_unique_id(pending_entry->unique_id()); | 823 entry->set_unique_id(pending_entry->unique_id()); |
| 819 | 824 |
| 820 DiscardNonCommittedEntriesInternal(); | 825 DiscardNonCommittedEntriesInternal(); |
| 821 | 826 |
| 822 int current_size = static_cast<int>(entries_.size()); | 827 int current_size = static_cast<int>(entries_.size()); |
| 823 | 828 |
| 824 // Prune any entries which are in front of the current entry. | |
| 825 if (current_size > 0) { | 829 if (current_size > 0) { |
| 830 // Prune any entries which are in front of the current entry. |
| 831 // Also prune the current entry if we are to replace the current entry. |
| 832 int prune_up_to = replace ? last_committed_entry_index_ - 1 |
| 833 : last_committed_entry_index_; |
| 826 int num_pruned = 0; | 834 int num_pruned = 0; |
| 827 while (last_committed_entry_index_ < (current_size - 1)) { | 835 while (prune_up_to < (current_size - 1)) { |
| 828 num_pruned++; | 836 num_pruned++; |
| 829 entries_.pop_back(); | 837 entries_.pop_back(); |
| 830 current_size--; | 838 current_size--; |
| 831 } | 839 } |
| 832 if (num_pruned > 0) // Only notify if we did prune something. | 840 if (num_pruned > 0) // Only notify if we did prune something. |
| 833 NotifyPrunedEntries(this, false, num_pruned); | 841 NotifyPrunedEntries(this, false, num_pruned); |
| 834 } | 842 } |
| 835 | 843 |
| 836 if (entries_.size() >= max_entry_count_) { | 844 if (entries_.size() >= max_entry_count_) { |
| 837 RemoveEntryAtIndex(0, GURL()); | 845 RemoveEntryAtIndex(0, GURL()); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 return i; | 965 return i; |
| 958 } | 966 } |
| 959 return -1; | 967 return -1; |
| 960 } | 968 } |
| 961 | 969 |
| 962 NavigationEntry* NavigationController::GetTransientEntry() const { | 970 NavigationEntry* NavigationController::GetTransientEntry() const { |
| 963 if (transient_entry_index_ == -1) | 971 if (transient_entry_index_ == -1) |
| 964 return NULL; | 972 return NULL; |
| 965 return entries_[transient_entry_index_].get(); | 973 return entries_[transient_entry_index_].get(); |
| 966 } | 974 } |
| OLD | NEW |