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 "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "base/time.h" | 10 #include "base/time.h" |
(...skipping 717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 new_entry = new NavigationEntry(active_contents_->type()); | 728 new_entry = new NavigationEntry(active_contents_->type()); |
729 } | 729 } |
730 | 730 |
731 new_entry->set_url(params.url); | 731 new_entry->set_url(params.url); |
732 new_entry->set_referrer(params.referrer); | 732 new_entry->set_referrer(params.referrer); |
733 new_entry->set_page_id(params.page_id); | 733 new_entry->set_page_id(params.page_id); |
734 new_entry->set_transition_type(params.transition); | 734 new_entry->set_transition_type(params.transition); |
735 new_entry->set_site_instance(active_contents_->GetSiteInstance()); | 735 new_entry->set_site_instance(active_contents_->GetSiteInstance()); |
736 new_entry->set_has_post_data(params.is_post); | 736 new_entry->set_has_post_data(params.is_post); |
737 | 737 |
738 // If the current entry is a redirection source, it needs to be replaced with | 738 InsertEntry(new_entry); |
739 // the new entry to avoid unwanted redirections in navigating backward / | |
740 // forward. Otherwise, just insert the new entry. | |
741 InsertOrReplaceEntry(new_entry, | |
742 PageTransition::IsRedirect(new_entry->transition_type())); | |
743 } | 739 } |
744 | 740 |
745 void NavigationController::RendererDidNavigateToExistingPage( | 741 void NavigationController::RendererDidNavigateToExistingPage( |
746 const ViewHostMsg_FrameNavigate_Params& params) { | 742 const ViewHostMsg_FrameNavigate_Params& params) { |
747 // We should only get here for main frame navigations. | 743 // We should only get here for main frame navigations. |
748 DCHECK(PageTransition::IsMainFrame(params.transition)); | 744 DCHECK(PageTransition::IsMainFrame(params.transition)); |
749 | 745 |
750 // This is a back/forward navigation. The existing page for the ID is | 746 // This is a back/forward navigation. The existing page for the ID is |
751 // guaranteed to exist by ClassifyNavigation, and we just need to update it | 747 // guaranteed to exist by ClassifyNavigation, and we just need to update it |
752 // with new information from the renderer. | 748 // with new information from the renderer. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
805 active_contents_->type(), | 801 active_contents_->type(), |
806 active_contents_->GetSiteInstance(), | 802 active_contents_->GetSiteInstance(), |
807 params.page_id); | 803 params.page_id); |
808 | 804 |
809 // Reference fragment navigation. We're guaranteed to have the last_committed | 805 // Reference fragment navigation. We're guaranteed to have the last_committed |
810 // entry and it will be the same page as the new navigation (minus the | 806 // entry and it will be the same page as the new navigation (minus the |
811 // reference fragments, of course). | 807 // reference fragments, of course). |
812 NavigationEntry* new_entry = new NavigationEntry(*existing_entry); | 808 NavigationEntry* new_entry = new NavigationEntry(*existing_entry); |
813 new_entry->set_page_id(params.page_id); | 809 new_entry->set_page_id(params.page_id); |
814 new_entry->set_url(params.url); | 810 new_entry->set_url(params.url); |
815 InsertOrReplaceEntry(new_entry, false); | 811 InsertEntry(new_entry); |
816 } | 812 } |
817 | 813 |
818 void NavigationController::RendererDidNavigateNewSubframe( | 814 void NavigationController::RendererDidNavigateNewSubframe( |
819 const ViewHostMsg_FrameNavigate_Params& params) { | 815 const ViewHostMsg_FrameNavigate_Params& params) { |
820 // Manual subframe navigations just get the current entry cloned so the user | 816 // Manual subframe navigations just get the current entry cloned so the user |
821 // can go back or forward to it. The actual subframe information will be | 817 // can go back or forward to it. The actual subframe information will be |
822 // stored in the page state for each of those entries. This happens out of | 818 // stored in the page state for each of those entries. This happens out of |
823 // band with the actual navigations. | 819 // band with the actual navigations. |
824 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " | 820 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " |
825 << "that a last committed entry exists."; | 821 << "that a last committed entry exists."; |
826 NavigationEntry* new_entry = new NavigationEntry(*GetLastCommittedEntry()); | 822 NavigationEntry* new_entry = new NavigationEntry(*GetLastCommittedEntry()); |
827 new_entry->set_page_id(params.page_id); | 823 new_entry->set_page_id(params.page_id); |
828 InsertOrReplaceEntry(new_entry, false); | 824 InsertEntry(new_entry); |
829 } | 825 } |
830 | 826 |
831 bool NavigationController::RendererDidNavigateAutoSubframe( | 827 bool NavigationController::RendererDidNavigateAutoSubframe( |
832 const ViewHostMsg_FrameNavigate_Params& params) { | 828 const ViewHostMsg_FrameNavigate_Params& params) { |
833 // We're guaranteed to have a previously committed entry, and we now need to | 829 // We're guaranteed to have a previously committed entry, and we now need to |
834 // handle navigation inside of a subframe in it without creating a new entry. | 830 // handle navigation inside of a subframe in it without creating a new entry. |
835 DCHECK(GetLastCommittedEntry()); | 831 DCHECK(GetLastCommittedEntry()); |
836 | 832 |
837 // Handle the case where we're navigating back/forward to a previous subframe | 833 // Handle the case where we're navigating back/forward to a previous subframe |
838 // navigation entry. This is case "2." in NAV_AUTO_SUBFRAME comment in the | 834 // 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... |
874 // This is a previous navigation (back/forward) that we're just now | 870 // This is a previous navigation (back/forward) that we're just now |
875 // committing. Just mark it as committed. | 871 // committing. Just mark it as committed. |
876 details.type = NavigationType::EXISTING_PAGE; | 872 details.type = NavigationType::EXISTING_PAGE; |
877 int new_entry_index = pending_entry_index_; | 873 int new_entry_index = pending_entry_index_; |
878 DiscardNonCommittedEntriesInternal(); | 874 DiscardNonCommittedEntriesInternal(); |
879 | 875 |
880 // Mark that entry as committed. | 876 // Mark that entry as committed. |
881 last_committed_entry_index_ = new_entry_index; | 877 last_committed_entry_index_ = new_entry_index; |
882 } else { | 878 } else { |
883 // This is a new navigation. It's easiest to just copy the entry and insert | 879 // This is a new navigation. It's easiest to just copy the entry and insert |
884 // it new again, since InsertOrReplaceEntry expects to take ownership and | 880 // it new again, since InsertEntry expects to take ownership and also |
885 // also discard the pending entry. We also need to synthesize a page ID. We | 881 // discard the pending entry. We also need to synthesize a page ID. We can |
886 // can only do this because this function will only be called by our custom | 882 // only do this because this function will only be called by our custom |
887 // TabContents types. For WebContents, the IDs are generated by the | 883 // TabContents types. For WebContents, the IDs are generated by the |
888 // renderer, so we can't do this. | 884 // renderer, so we can't do this. |
889 details.type = NavigationType::NEW_PAGE; | 885 details.type = NavigationType::NEW_PAGE; |
890 pending_entry_->set_page_id(active_contents_->GetMaxPageID() + 1); | 886 pending_entry_->set_page_id(active_contents_->GetMaxPageID() + 1); |
891 active_contents_->UpdateMaxPageID(pending_entry_->page_id()); | 887 active_contents_->UpdateMaxPageID(pending_entry_->page_id()); |
892 InsertOrReplaceEntry(new NavigationEntry(*pending_entry_), false); | 888 InsertEntry(new NavigationEntry(*pending_entry_)); |
893 } | 889 } |
894 | 890 |
895 // Broadcast the notification of the navigation. | 891 // Broadcast the notification of the navigation. |
896 details.entry = GetActiveEntry(); | 892 details.entry = GetActiveEntry(); |
897 details.is_auto = false; | 893 details.is_auto = false; |
898 details.is_in_page = AreURLsInPageNavigation(details.previous_url, | 894 details.is_in_page = AreURLsInPageNavigation(details.previous_url, |
899 details.entry->url()); | 895 details.entry->url()); |
900 details.is_main_frame = true; | 896 details.is_main_frame = true; |
901 NotifyNavigationEntryCommitted(&details); | 897 NotifyNavigationEntryCommitted(&details); |
902 } | 898 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 } | 947 } |
952 | 948 |
953 // If there was a transient entry, invalidate everything so the new active | 949 // If there was a transient entry, invalidate everything so the new active |
954 // entry state is shown. | 950 // entry state is shown. |
955 if (transient) { | 951 if (transient) { |
956 active_contents_->NotifyNavigationStateChanged( | 952 active_contents_->NotifyNavigationStateChanged( |
957 TabContents::INVALIDATE_EVERYTHING); | 953 TabContents::INVALIDATE_EVERYTHING); |
958 } | 954 } |
959 } | 955 } |
960 | 956 |
961 void NavigationController::InsertOrReplaceEntry(NavigationEntry* entry, | 957 void NavigationController::InsertEntry(NavigationEntry* entry) { |
962 bool replace) { | |
963 DCHECK(entry->transition_type() != PageTransition::AUTO_SUBFRAME); | 958 DCHECK(entry->transition_type() != PageTransition::AUTO_SUBFRAME); |
964 | 959 |
965 // Copy the pending entry's unique ID to the committed entry. | 960 // Copy the pending entry's unique ID to the committed entry. |
966 // I don't know if pending_entry_index_ can be other than -1 here. | 961 // I don't know if pending_entry_index_ can be other than -1 here. |
967 const NavigationEntry* const pending_entry = (pending_entry_index_ == -1) ? | 962 const NavigationEntry* const pending_entry = (pending_entry_index_ == -1) ? |
968 pending_entry_ : entries_[pending_entry_index_].get(); | 963 pending_entry_ : entries_[pending_entry_index_].get(); |
969 if (pending_entry) | 964 if (pending_entry) |
970 entry->set_unique_id(pending_entry->unique_id()); | 965 entry->set_unique_id(pending_entry->unique_id()); |
971 | 966 |
972 DiscardNonCommittedEntriesInternal(); | 967 DiscardNonCommittedEntriesInternal(); |
973 | 968 |
974 int current_size = static_cast<int>(entries_.size()); | 969 int current_size = static_cast<int>(entries_.size()); |
975 | 970 |
| 971 // Prune any entries which are in front of the current entry. |
976 if (current_size > 0) { | 972 if (current_size > 0) { |
977 // Prune any entries which are in front of the current entry. | |
978 // Also prune the current entry if we are to replace the current entry. | |
979 int prune_up_to = replace ? last_committed_entry_index_ - 1 | |
980 : last_committed_entry_index_; | |
981 int num_pruned = 0; | 973 int num_pruned = 0; |
982 while (prune_up_to < (current_size - 1)) { | 974 while (last_committed_entry_index_ < (current_size - 1)) { |
983 num_pruned++; | 975 num_pruned++; |
984 entries_.pop_back(); | 976 entries_.pop_back(); |
985 current_size--; | 977 current_size--; |
986 } | 978 } |
987 if (num_pruned > 0) // Only notify if we did prune something. | 979 if (num_pruned > 0) // Only notify if we did prune something. |
988 NotifyPrunedEntries(this, false, num_pruned); | 980 NotifyPrunedEntries(this, false, num_pruned); |
989 } | 981 } |
990 | 982 |
991 if (entries_.size() >= max_entry_count_) { | 983 if (entries_.size() >= max_entry_count_) { |
992 RemoveEntryAtIndex(0, GURL()); | 984 RemoveEntryAtIndex(0, GURL()); |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1236 return i; | 1228 return i; |
1237 } | 1229 } |
1238 return -1; | 1230 return -1; |
1239 } | 1231 } |
1240 | 1232 |
1241 NavigationEntry* NavigationController::GetTransientEntry() const { | 1233 NavigationEntry* NavigationController::GetTransientEntry() const { |
1242 if (transient_entry_index_ == -1) | 1234 if (transient_entry_index_ == -1) |
1243 return NULL; | 1235 return NULL; |
1244 return entries_[transient_entry_index_].get(); | 1236 return entries_[transient_entry_index_].get(); |
1245 } | 1237 } |
OLD | NEW |