| 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 |