Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(481)

Side by Side Diff: chrome/browser/tab_contents/navigation_controller.cc

Issue 100245: Make forward/backward navigation work even when redirection is involved. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « chrome/browser/tab_contents/navigation_controller.h ('k') | chrome/test/data/History/HistoryHelper.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698