| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/browser/frame_host/navigation_controller_impl.h" | 5 #include "content/browser/frame_host/navigation_controller_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 default: | 747 default: |
| 748 NOTREACHED(); | 748 NOTREACHED(); |
| 749 break; | 749 break; |
| 750 }; | 750 }; |
| 751 | 751 |
| 752 LoadEntry(entry); | 752 LoadEntry(entry); |
| 753 } | 753 } |
| 754 | 754 |
| 755 bool NavigationControllerImpl::RendererDidNavigate( | 755 bool NavigationControllerImpl::RendererDidNavigate( |
| 756 RenderFrameHost* rfh, | 756 RenderFrameHost* rfh, |
| 757 int32 page_id, |
| 757 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, | 758 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, |
| 758 LoadCommittedDetails* details) { | 759 LoadCommittedDetails* details) { |
| 759 is_initial_navigation_ = false; | 760 is_initial_navigation_ = false; |
| 760 | 761 |
| 761 // Save the previous state before we clobber it. | 762 // Save the previous state before we clobber it. |
| 762 if (GetLastCommittedEntry()) { | 763 if (GetLastCommittedEntry()) { |
| 763 details->previous_url = GetLastCommittedEntry()->GetURL(); | 764 details->previous_url = GetLastCommittedEntry()->GetURL(); |
| 764 details->previous_entry_index = GetLastCommittedEntryIndex(); | 765 details->previous_entry_index = GetLastCommittedEntryIndex(); |
| 765 } else { | 766 } else { |
| 766 details->previous_url = GURL(); | 767 details->previous_url = GURL(); |
| 767 details->previous_entry_index = -1; | 768 details->previous_entry_index = -1; |
| 768 } | 769 } |
| 769 | 770 |
| 770 // If we have a pending entry at this point, it should have a SiteInstance. | 771 // If we have a pending entry at this point, it should have a SiteInstance. |
| 771 // Restored entries start out with a null SiteInstance, but we should have | 772 // Restored entries start out with a null SiteInstance, but we should have |
| 772 // assigned one in NavigateToPendingEntry. | 773 // assigned one in NavigateToPendingEntry. |
| 773 DCHECK(pending_entry_index_ == -1 || pending_entry_->site_instance()); | 774 DCHECK(pending_entry_index_ == -1 || pending_entry_->site_instance()); |
| 774 | 775 |
| 775 // If we are doing a cross-site reload, we need to replace the existing | 776 // If we are doing a cross-site reload, we need to replace the existing |
| 776 // navigation entry, not add another entry to the history. This has the side | 777 // navigation entry, not add another entry to the history. This has the side |
| 777 // effect of removing forward browsing history, if such existed. | 778 // effect of removing forward browsing history, if such existed. |
| 778 // Or if we are doing a cross-site redirect navigation, | 779 // Or if we are doing a cross-site redirect navigation, |
| 779 // we will do a similar thing. | 780 // we will do a similar thing. |
| 780 details->did_replace_entry = | 781 details->did_replace_entry = |
| 781 pending_entry_ && pending_entry_->should_replace_entry(); | 782 pending_entry_ && pending_entry_->should_replace_entry(); |
| 782 | 783 |
| 783 // Do navigation-type specific actions. These will make and commit an entry. | 784 // Do navigation-type specific actions. These will make and commit an entry. |
| 784 details->type = ClassifyNavigation(rfh, params); | 785 details->type = ClassifyNavigation(rfh, page_id, params); |
| 785 | 786 |
| 786 // is_in_page must be computed before the entry gets committed. | 787 // is_in_page must be computed before the entry gets committed. |
| 787 details->is_in_page = AreURLsInPageNavigation(rfh->GetLastCommittedURL(), | 788 details->is_in_page = AreURLsInPageNavigation(rfh->GetLastCommittedURL(), |
| 788 params.url, params.was_within_same_page, rfh); | 789 params.url, params.was_within_same_page, rfh); |
| 789 | 790 |
| 790 switch (details->type) { | 791 switch (details->type) { |
| 791 case NAVIGATION_TYPE_NEW_PAGE: | 792 case NAVIGATION_TYPE_NEW_PAGE: |
| 792 RendererDidNavigateToNewPage(rfh, params, details->did_replace_entry); | 793 RendererDidNavigateToNewPage(rfh, page_id, params, |
| 794 details->did_replace_entry); |
| 793 break; | 795 break; |
| 794 case NAVIGATION_TYPE_EXISTING_PAGE: | 796 case NAVIGATION_TYPE_EXISTING_PAGE: |
| 795 RendererDidNavigateToExistingPage(rfh, params); | 797 RendererDidNavigateToExistingPage(rfh, page_id, params); |
| 796 break; | 798 break; |
| 797 case NAVIGATION_TYPE_SAME_PAGE: | 799 case NAVIGATION_TYPE_SAME_PAGE: |
| 798 RendererDidNavigateToSamePage(rfh, params); | 800 RendererDidNavigateToSamePage(rfh, page_id, params); |
| 799 break; | 801 break; |
| 800 case NAVIGATION_TYPE_IN_PAGE: | 802 case NAVIGATION_TYPE_IN_PAGE: |
| 801 RendererDidNavigateInPage(rfh, params, &details->did_replace_entry); | 803 RendererDidNavigateInPage(rfh, page_id, params, |
| 804 &details->did_replace_entry); |
| 802 break; | 805 break; |
| 803 case NAVIGATION_TYPE_NEW_SUBFRAME: | 806 case NAVIGATION_TYPE_NEW_SUBFRAME: |
| 804 RendererDidNavigateNewSubframe(rfh, params); | 807 RendererDidNavigateNewSubframe(rfh, page_id, params); |
| 805 break; | 808 break; |
| 806 case NAVIGATION_TYPE_AUTO_SUBFRAME: | 809 case NAVIGATION_TYPE_AUTO_SUBFRAME: |
| 807 if (!RendererDidNavigateAutoSubframe(rfh, params)) | 810 if (!RendererDidNavigateAutoSubframe(rfh, page_id, params)) |
| 808 return false; | 811 return false; |
| 809 break; | 812 break; |
| 810 case NAVIGATION_TYPE_NAV_IGNORE: | 813 case NAVIGATION_TYPE_NAV_IGNORE: |
| 811 // If a pending navigation was in progress, this canceled it. We should | 814 // If a pending navigation was in progress, this canceled it. We should |
| 812 // discard it and make sure it is removed from the URL bar. After that, | 815 // discard it and make sure it is removed from the URL bar. After that, |
| 813 // there is nothing we can do with this navigation, so we just return to | 816 // there is nothing we can do with this navigation, so we just return to |
| 814 // the caller that nothing has happened. | 817 // the caller that nothing has happened. |
| 815 if (pending_entry_) { | 818 if (pending_entry_) { |
| 816 DiscardNonCommittedEntries(); | 819 DiscardNonCommittedEntries(); |
| 817 delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_URL); | 820 delegate_->NotifyNavigationStateChanged(INVALIDATE_TYPE_URL); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 874 ui::PageTransitionIsMainFrame(params.transition); | 877 ui::PageTransitionIsMainFrame(params.transition); |
| 875 details->serialized_security_info = params.security_info; | 878 details->serialized_security_info = params.security_info; |
| 876 details->http_status_code = params.http_status_code; | 879 details->http_status_code = params.http_status_code; |
| 877 NotifyNavigationEntryCommitted(details); | 880 NotifyNavigationEntryCommitted(details); |
| 878 | 881 |
| 879 return true; | 882 return true; |
| 880 } | 883 } |
| 881 | 884 |
| 882 NavigationType NavigationControllerImpl::ClassifyNavigation( | 885 NavigationType NavigationControllerImpl::ClassifyNavigation( |
| 883 RenderFrameHost* rfh, | 886 RenderFrameHost* rfh, |
| 887 int32 page_id, |
| 884 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) const { | 888 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) const { |
| 885 if (params.page_id == -1) { | 889 if (page_id == -1) { |
| 886 // TODO(nasko, creis): An out-of-process child frame has no way of | 890 // TODO(nasko, creis): An out-of-process child frame has no way of |
| 887 // knowing the page_id of its parent, so it is passing back -1. The | 891 // knowing the page_id of its parent, so it is passing back -1. The |
| 888 // semantics here should be re-evaluated during session history refactor | 892 // semantics here should be re-evaluated during session history refactor |
| 889 // (see http://crbug.com/236848). For now, we assume this means the | 893 // (see http://crbug.com/236848). For now, we assume this means the |
| 890 // child frame loaded and proceed. Note that this may do the wrong thing | 894 // child frame loaded and proceed. Note that this may do the wrong thing |
| 891 // for cross-process AUTO_SUBFRAME navigations. | 895 // for cross-process AUTO_SUBFRAME navigations. |
| 892 if (rfh->IsCrossProcessSubframe()) | 896 if (rfh->IsCrossProcessSubframe()) |
| 893 return NAVIGATION_TYPE_NEW_SUBFRAME; | 897 return NAVIGATION_TYPE_NEW_SUBFRAME; |
| 894 | 898 |
| 895 // The renderer generates the page IDs, and so if it gives us the invalid | 899 // The renderer generates the page IDs, and so if it gives us the invalid |
| (...skipping 10 matching lines...) Expand all Loading... |
| 906 // could be invalid. This can also happen for a cross-site transition | 910 // could be invalid. This can also happen for a cross-site transition |
| 907 // that causes us to swap processes. Then the error page load will be in | 911 // that causes us to swap processes. Then the error page load will be in |
| 908 // a new process with no page IDs ever assigned (and hence a -1 value), | 912 // a new process with no page IDs ever assigned (and hence a -1 value), |
| 909 // yet the navigation controller still might have previous pages in its | 913 // yet the navigation controller still might have previous pages in its |
| 910 // list. | 914 // list. |
| 911 // | 915 // |
| 912 // In these cases, there's nothing we can do with them, so ignore. | 916 // In these cases, there's nothing we can do with them, so ignore. |
| 913 return NAVIGATION_TYPE_NAV_IGNORE; | 917 return NAVIGATION_TYPE_NAV_IGNORE; |
| 914 } | 918 } |
| 915 | 919 |
| 916 if (params.page_id > delegate_->GetMaxPageIDForSiteInstance( | 920 if (page_id > delegate_->GetMaxPageIDForSiteInstance( |
| 917 rfh->GetSiteInstance())) { | 921 rfh->GetSiteInstance())) { |
| 918 // Greater page IDs than we've ever seen before are new pages. We may or may | 922 // Greater page IDs than we've ever seen before are new pages. We may or may |
| 919 // not have a pending entry for the page, and this may or may not be the | 923 // not have a pending entry for the page, and this may or may not be the |
| 920 // main frame. | 924 // main frame. |
| 921 if (ui::PageTransitionIsMainFrame(params.transition)) | 925 if (ui::PageTransitionIsMainFrame(params.transition)) |
| 922 return NAVIGATION_TYPE_NEW_PAGE; | 926 return NAVIGATION_TYPE_NEW_PAGE; |
| 923 | 927 |
| 924 // When this is a new subframe navigation, we should have a committed page | 928 // When this is a new subframe navigation, we should have a committed page |
| 925 // for which it's a suframe in. This may not be the case when an iframe is | 929 // for which it's a suframe in. This may not be the case when an iframe is |
| 926 // navigated on a popup navigated to about:blank (the iframe would be | 930 // navigated on a popup navigated to about:blank (the iframe would be |
| 927 // written into the popup by script on the main page). For these cases, | 931 // written into the popup by script on the main page). For these cases, |
| 928 // there isn't any navigation stuff we can do, so just ignore it. | 932 // there isn't any navigation stuff we can do, so just ignore it. |
| 929 if (!GetLastCommittedEntry()) | 933 if (!GetLastCommittedEntry()) |
| 930 return NAVIGATION_TYPE_NAV_IGNORE; | 934 return NAVIGATION_TYPE_NAV_IGNORE; |
| 931 | 935 |
| 932 // Valid subframe navigation. | 936 // Valid subframe navigation. |
| 933 return NAVIGATION_TYPE_NEW_SUBFRAME; | 937 return NAVIGATION_TYPE_NEW_SUBFRAME; |
| 934 } | 938 } |
| 935 | 939 |
| 936 // We only clear the session history when navigating to a new page. | 940 // We only clear the session history when navigating to a new page. |
| 937 DCHECK(!params.history_list_was_cleared); | 941 DCHECK(!params.history_list_was_cleared); |
| 938 | 942 |
| 939 // Now we know that the notification is for an existing page. Find that entry. | 943 // Now we know that the notification is for an existing page. Find that entry. |
| 940 int existing_entry_index = GetEntryIndexWithPageID( | 944 int existing_entry_index = GetEntryIndexWithPageID( |
| 941 rfh->GetSiteInstance(), | 945 rfh->GetSiteInstance(), |
| 942 params.page_id); | 946 page_id); |
| 943 if (existing_entry_index == -1) { | 947 if (existing_entry_index == -1) { |
| 944 // The page was not found. It could have been pruned because of the limit on | 948 // The page was not found. It could have been pruned because of the limit on |
| 945 // back/forward entries (not likely since we'll usually tell it to navigate | 949 // back/forward entries (not likely since we'll usually tell it to navigate |
| 946 // to such entries). It could also mean that the renderer is smoking crack. | 950 // to such entries). It could also mean that the renderer is smoking crack. |
| 947 NOTREACHED(); | 951 NOTREACHED(); |
| 948 | 952 |
| 949 // Because the unknown entry has committed, we risk showing the wrong URL in | 953 // Because the unknown entry has committed, we risk showing the wrong URL in |
| 950 // release builds. Instead, we'll kill the renderer process to be safe. | 954 // release builds. Instead, we'll kill the renderer process to be safe. |
| 951 LOG(ERROR) << "terminating renderer for bad navigation: " << params.url; | 955 LOG(ERROR) << "terminating renderer for bad navigation: " << params.url; |
| 952 RecordAction(base::UserMetricsAction("BadMessageTerminate_NC")); | 956 RecordAction(base::UserMetricsAction("BadMessageTerminate_NC")); |
| 953 | 957 |
| 954 // Temporary code so we can get more information. Format: | 958 // Temporary code so we can get more information. Format: |
| 955 // http://url/foo.html#page1#max3#frame1#ids:2_Nx,1_1x,3_2 | 959 // http://url/foo.html#page1#max3#frame1#ids:2_Nx,1_1x,3_2 |
| 956 std::string temp = params.url.spec(); | 960 std::string temp = params.url.spec(); |
| 957 temp.append("#page"); | 961 temp.append("#page"); |
| 958 temp.append(base::IntToString(params.page_id)); | 962 temp.append(base::IntToString(page_id)); |
| 959 temp.append("#max"); | 963 temp.append("#max"); |
| 960 temp.append(base::IntToString(delegate_->GetMaxPageID())); | 964 temp.append(base::IntToString(delegate_->GetMaxPageID())); |
| 961 temp.append("#frame"); | 965 temp.append("#frame"); |
| 962 temp.append(base::IntToString(rfh->GetRoutingID())); | 966 temp.append(base::IntToString(rfh->GetRoutingID())); |
| 963 temp.append("#ids"); | 967 temp.append("#ids"); |
| 964 for (int i = 0; i < static_cast<int>(entries_.size()); ++i) { | 968 for (int i = 0; i < static_cast<int>(entries_.size()); ++i) { |
| 965 // Append entry metadata (e.g., 3_7x): | 969 // Append entry metadata (e.g., 3_7x): |
| 966 // 3: page_id | 970 // 3: page_id |
| 967 // 7: SiteInstance ID, or N for null | 971 // 7: SiteInstance ID, or N for null |
| 968 // x: appended if not from the current SiteInstance | 972 // x: appended if not from the current SiteInstance |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1017 return NAVIGATION_TYPE_IN_PAGE; | 1021 return NAVIGATION_TYPE_IN_PAGE; |
| 1018 } | 1022 } |
| 1019 | 1023 |
| 1020 // Since we weeded out "new" navigations above, we know this is an existing | 1024 // Since we weeded out "new" navigations above, we know this is an existing |
| 1021 // (back/forward) navigation. | 1025 // (back/forward) navigation. |
| 1022 return NAVIGATION_TYPE_EXISTING_PAGE; | 1026 return NAVIGATION_TYPE_EXISTING_PAGE; |
| 1023 } | 1027 } |
| 1024 | 1028 |
| 1025 void NavigationControllerImpl::RendererDidNavigateToNewPage( | 1029 void NavigationControllerImpl::RendererDidNavigateToNewPage( |
| 1026 RenderFrameHost* rfh, | 1030 RenderFrameHost* rfh, |
| 1031 int32 page_id, |
| 1027 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, | 1032 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, |
| 1028 bool replace_entry) { | 1033 bool replace_entry) { |
| 1029 NavigationEntryImpl* new_entry; | 1034 NavigationEntryImpl* new_entry; |
| 1030 bool update_virtual_url; | 1035 bool update_virtual_url; |
| 1031 // Only make a copy of the pending entry if it is appropriate for the new page | 1036 // Only make a copy of the pending entry if it is appropriate for the new page |
| 1032 // that was just loaded. We verify this at a coarse grain by checking that | 1037 // that was just loaded. We verify this at a coarse grain by checking that |
| 1033 // the SiteInstance hasn't been assigned to something else. | 1038 // the SiteInstance hasn't been assigned to something else. |
| 1034 if (pending_entry_ && | 1039 if (pending_entry_ && |
| 1035 (!pending_entry_->site_instance() || | 1040 (!pending_entry_->site_instance() || |
| 1036 pending_entry_->site_instance() == rfh->GetSiteInstance())) { | 1041 pending_entry_->site_instance() == rfh->GetSiteInstance())) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1059 // the URL. | 1064 // the URL. |
| 1060 update_virtual_url = needs_update; | 1065 update_virtual_url = needs_update; |
| 1061 } | 1066 } |
| 1062 | 1067 |
| 1063 if (params.url_is_unreachable) | 1068 if (params.url_is_unreachable) |
| 1064 new_entry->set_page_type(PAGE_TYPE_ERROR); | 1069 new_entry->set_page_type(PAGE_TYPE_ERROR); |
| 1065 new_entry->SetURL(params.url); | 1070 new_entry->SetURL(params.url); |
| 1066 if (update_virtual_url) | 1071 if (update_virtual_url) |
| 1067 UpdateVirtualURLToURL(new_entry, params.url); | 1072 UpdateVirtualURLToURL(new_entry, params.url); |
| 1068 new_entry->SetReferrer(params.referrer); | 1073 new_entry->SetReferrer(params.referrer); |
| 1069 new_entry->SetPageID(params.page_id); | 1074 new_entry->SetPageID(page_id); |
| 1070 new_entry->SetTransitionType(params.transition); | 1075 new_entry->SetTransitionType(params.transition); |
| 1071 new_entry->set_site_instance( | 1076 new_entry->set_site_instance( |
| 1072 static_cast<SiteInstanceImpl*>(rfh->GetSiteInstance())); | 1077 static_cast<SiteInstanceImpl*>(rfh->GetSiteInstance())); |
| 1073 new_entry->SetHasPostData(params.is_post); | 1078 new_entry->SetHasPostData(params.is_post); |
| 1074 new_entry->SetPostID(params.post_id); | 1079 new_entry->SetPostID(params.post_id); |
| 1075 new_entry->SetOriginalRequestURL(params.original_request_url); | 1080 new_entry->SetOriginalRequestURL(params.original_request_url); |
| 1076 new_entry->SetIsOverridingUserAgent(params.is_overriding_user_agent); | 1081 new_entry->SetIsOverridingUserAgent(params.is_overriding_user_agent); |
| 1077 | 1082 |
| 1078 // history.pushState() is classified as a navigation to a new page, but | 1083 // history.pushState() is classified as a navigation to a new page, but |
| 1079 // sets was_within_same_page to true. In this case, we already have the | 1084 // sets was_within_same_page to true. In this case, we already have the |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1091 DiscardNonCommittedEntriesInternal(); | 1096 DiscardNonCommittedEntriesInternal(); |
| 1092 entries_.clear(); | 1097 entries_.clear(); |
| 1093 last_committed_entry_index_ = -1; | 1098 last_committed_entry_index_ = -1; |
| 1094 } | 1099 } |
| 1095 | 1100 |
| 1096 InsertOrReplaceEntry(new_entry, replace_entry); | 1101 InsertOrReplaceEntry(new_entry, replace_entry); |
| 1097 } | 1102 } |
| 1098 | 1103 |
| 1099 void NavigationControllerImpl::RendererDidNavigateToExistingPage( | 1104 void NavigationControllerImpl::RendererDidNavigateToExistingPage( |
| 1100 RenderFrameHost* rfh, | 1105 RenderFrameHost* rfh, |
| 1106 int32 page_id, |
| 1101 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { | 1107 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { |
| 1102 // We should only get here for main frame navigations. | 1108 // We should only get here for main frame navigations. |
| 1103 DCHECK(ui::PageTransitionIsMainFrame(params.transition)); | 1109 DCHECK(ui::PageTransitionIsMainFrame(params.transition)); |
| 1104 | 1110 |
| 1105 // This is a back/forward navigation. The existing page for the ID is | 1111 // This is a back/forward navigation. The existing page for the ID is |
| 1106 // guaranteed to exist by ClassifyNavigation, and we just need to update it | 1112 // guaranteed to exist by ClassifyNavigation, and we just need to update it |
| 1107 // with new information from the renderer. | 1113 // with new information from the renderer. |
| 1108 int entry_index = GetEntryIndexWithPageID(rfh->GetSiteInstance(), | 1114 int entry_index = GetEntryIndexWithPageID(rfh->GetSiteInstance(), page_id); |
| 1109 params.page_id); | |
| 1110 DCHECK(entry_index >= 0 && | 1115 DCHECK(entry_index >= 0 && |
| 1111 entry_index < static_cast<int>(entries_.size())); | 1116 entry_index < static_cast<int>(entries_.size())); |
| 1112 NavigationEntryImpl* entry = entries_[entry_index].get(); | 1117 NavigationEntryImpl* entry = entries_[entry_index].get(); |
| 1113 | 1118 |
| 1114 // The URL may have changed due to redirects. | 1119 // The URL may have changed due to redirects. |
| 1115 entry->SetURL(params.url); | 1120 entry->SetURL(params.url); |
| 1116 entry->SetReferrer(params.referrer); | 1121 entry->SetReferrer(params.referrer); |
| 1117 if (entry->update_virtual_url_with_url()) | 1122 if (entry->update_virtual_url_with_url()) |
| 1118 UpdateVirtualURLToURL(entry, params.url); | 1123 UpdateVirtualURLToURL(entry, params.url); |
| 1119 | 1124 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1139 // is now likely canceled. If it is not canceled, we will treat it as a new | 1144 // is now likely canceled. If it is not canceled, we will treat it as a new |
| 1140 // navigation when it arrives, which is also ok. | 1145 // navigation when it arrives, which is also ok. |
| 1141 // | 1146 // |
| 1142 // Note that we need to use the "internal" version since we don't want to | 1147 // Note that we need to use the "internal" version since we don't want to |
| 1143 // actually change any other state, just kill the pointer. | 1148 // actually change any other state, just kill the pointer. |
| 1144 DiscardNonCommittedEntriesInternal(); | 1149 DiscardNonCommittedEntriesInternal(); |
| 1145 | 1150 |
| 1146 // If a transient entry was removed, the indices might have changed, so we | 1151 // If a transient entry was removed, the indices might have changed, so we |
| 1147 // have to query the entry index again. | 1152 // have to query the entry index again. |
| 1148 last_committed_entry_index_ = | 1153 last_committed_entry_index_ = |
| 1149 GetEntryIndexWithPageID(rfh->GetSiteInstance(), params.page_id); | 1154 GetEntryIndexWithPageID(rfh->GetSiteInstance(), page_id); |
| 1150 } | 1155 } |
| 1151 | 1156 |
| 1152 void NavigationControllerImpl::RendererDidNavigateToSamePage( | 1157 void NavigationControllerImpl::RendererDidNavigateToSamePage( |
| 1153 RenderFrameHost* rfh, | 1158 RenderFrameHost* rfh, |
| 1159 int32 page_id, |
| 1154 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { | 1160 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { |
| 1155 // This mode implies we have a pending entry that's the same as an existing | 1161 // This mode implies we have a pending entry that's the same as an existing |
| 1156 // entry for this page ID. This entry is guaranteed to exist by | 1162 // entry for this page ID. This entry is guaranteed to exist by |
| 1157 // ClassifyNavigation. All we need to do is update the existing entry. | 1163 // ClassifyNavigation. All we need to do is update the existing entry. |
| 1158 NavigationEntryImpl* existing_entry = GetEntryWithPageID( | 1164 NavigationEntryImpl* existing_entry = GetEntryWithPageID( |
| 1159 rfh->GetSiteInstance(), params.page_id); | 1165 rfh->GetSiteInstance(), page_id); |
| 1160 | 1166 |
| 1161 // We assign the entry's unique ID to be that of the new one. Since this is | 1167 // We assign the entry's unique ID to be that of the new one. Since this is |
| 1162 // always the result of a user action, we want to dismiss infobars, etc. like | 1168 // always the result of a user action, we want to dismiss infobars, etc. like |
| 1163 // a regular user-initiated navigation. | 1169 // a regular user-initiated navigation. |
| 1164 existing_entry->set_unique_id(pending_entry_->GetUniqueID()); | 1170 existing_entry->set_unique_id(pending_entry_->GetUniqueID()); |
| 1165 | 1171 |
| 1166 // The URL may have changed due to redirects. | 1172 // The URL may have changed due to redirects. |
| 1167 if (existing_entry->update_virtual_url_with_url()) | 1173 if (existing_entry->update_virtual_url_with_url()) |
| 1168 UpdateVirtualURLToURL(existing_entry, params.url); | 1174 UpdateVirtualURLToURL(existing_entry, params.url); |
| 1169 existing_entry->SetURL(params.url); | 1175 existing_entry->SetURL(params.url); |
| 1170 existing_entry->SetReferrer(params.referrer); | 1176 existing_entry->SetReferrer(params.referrer); |
| 1171 | 1177 |
| 1172 // The page may have been requested with a different HTTP method. | 1178 // The page may have been requested with a different HTTP method. |
| 1173 existing_entry->SetHasPostData(params.is_post); | 1179 existing_entry->SetHasPostData(params.is_post); |
| 1174 existing_entry->SetPostID(params.post_id); | 1180 existing_entry->SetPostID(params.post_id); |
| 1175 | 1181 |
| 1176 DiscardNonCommittedEntries(); | 1182 DiscardNonCommittedEntries(); |
| 1177 } | 1183 } |
| 1178 | 1184 |
| 1179 void NavigationControllerImpl::RendererDidNavigateInPage( | 1185 void NavigationControllerImpl::RendererDidNavigateInPage( |
| 1180 RenderFrameHost* rfh, | 1186 RenderFrameHost* rfh, |
| 1187 int32 page_id, |
| 1181 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, | 1188 const FrameHostMsg_DidCommitProvisionalLoad_Params& params, |
| 1182 bool* did_replace_entry) { | 1189 bool* did_replace_entry) { |
| 1183 DCHECK(ui::PageTransitionIsMainFrame(params.transition)) << | 1190 DCHECK(ui::PageTransitionIsMainFrame(params.transition)) << |
| 1184 "WebKit should only tell us about in-page navs for the main frame."; | 1191 "WebKit should only tell us about in-page navs for the main frame."; |
| 1185 // We're guaranteed to have an entry for this one. | 1192 // We're guaranteed to have an entry for this one. |
| 1186 NavigationEntryImpl* existing_entry = GetEntryWithPageID( | 1193 NavigationEntryImpl* existing_entry = GetEntryWithPageID( |
| 1187 rfh->GetSiteInstance(), params.page_id); | 1194 rfh->GetSiteInstance(), page_id); |
| 1188 | 1195 |
| 1189 // Reference fragment navigation. We're guaranteed to have the last_committed | 1196 // Reference fragment navigation. We're guaranteed to have the last_committed |
| 1190 // entry and it will be the same page as the new navigation (minus the | 1197 // entry and it will be the same page as the new navigation (minus the |
| 1191 // reference fragments, of course). We'll update the URL of the existing | 1198 // reference fragments, of course). We'll update the URL of the existing |
| 1192 // entry without pruning the forward history. | 1199 // entry without pruning the forward history. |
| 1193 existing_entry->SetURL(params.url); | 1200 existing_entry->SetURL(params.url); |
| 1194 if (existing_entry->update_virtual_url_with_url()) | 1201 if (existing_entry->update_virtual_url_with_url()) |
| 1195 UpdateVirtualURLToURL(existing_entry, params.url); | 1202 UpdateVirtualURLToURL(existing_entry, params.url); |
| 1196 | 1203 |
| 1197 existing_entry->SetHasPostData(params.is_post); | 1204 existing_entry->SetHasPostData(params.is_post); |
| 1198 existing_entry->SetPostID(params.post_id); | 1205 existing_entry->SetPostID(params.post_id); |
| 1199 | 1206 |
| 1200 // This replaces the existing entry since the page ID didn't change. | 1207 // This replaces the existing entry since the page ID didn't change. |
| 1201 *did_replace_entry = true; | 1208 *did_replace_entry = true; |
| 1202 | 1209 |
| 1203 DiscardNonCommittedEntriesInternal(); | 1210 DiscardNonCommittedEntriesInternal(); |
| 1204 | 1211 |
| 1205 // If a transient entry was removed, the indices might have changed, so we | 1212 // If a transient entry was removed, the indices might have changed, so we |
| 1206 // have to query the entry index again. | 1213 // have to query the entry index again. |
| 1207 last_committed_entry_index_ = | 1214 last_committed_entry_index_ = |
| 1208 GetEntryIndexWithPageID(rfh->GetSiteInstance(), params.page_id); | 1215 GetEntryIndexWithPageID(rfh->GetSiteInstance(), page_id); |
| 1209 } | 1216 } |
| 1210 | 1217 |
| 1211 void NavigationControllerImpl::RendererDidNavigateNewSubframe( | 1218 void NavigationControllerImpl::RendererDidNavigateNewSubframe( |
| 1212 RenderFrameHost* rfh, | 1219 RenderFrameHost* rfh, |
| 1220 int32 page_id, |
| 1213 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { | 1221 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { |
| 1214 if (ui::PageTransitionCoreTypeIs(params.transition, | 1222 if (ui::PageTransitionCoreTypeIs(params.transition, |
| 1215 ui::PAGE_TRANSITION_AUTO_SUBFRAME)) { | 1223 ui::PAGE_TRANSITION_AUTO_SUBFRAME)) { |
| 1216 // This is not user-initiated. Ignore. | 1224 // This is not user-initiated. Ignore. |
| 1217 DiscardNonCommittedEntriesInternal(); | 1225 DiscardNonCommittedEntriesInternal(); |
| 1218 return; | 1226 return; |
| 1219 } | 1227 } |
| 1220 | 1228 |
| 1221 // Manual subframe navigations just get the current entry cloned so the user | 1229 // Manual subframe navigations just get the current entry cloned so the user |
| 1222 // can go back or forward to it. The actual subframe information will be | 1230 // can go back or forward to it. The actual subframe information will be |
| 1223 // stored in the page state for each of those entries. This happens out of | 1231 // stored in the page state for each of those entries. This happens out of |
| 1224 // band with the actual navigations. | 1232 // band with the actual navigations. |
| 1225 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " | 1233 DCHECK(GetLastCommittedEntry()) << "ClassifyNavigation should guarantee " |
| 1226 << "that a last committed entry exists."; | 1234 << "that a last committed entry exists."; |
| 1227 NavigationEntryImpl* new_entry = new NavigationEntryImpl( | 1235 NavigationEntryImpl* new_entry = new NavigationEntryImpl( |
| 1228 *NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry())); | 1236 *NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry())); |
| 1229 new_entry->SetPageID(params.page_id); | 1237 new_entry->SetPageID(page_id); |
| 1230 InsertOrReplaceEntry(new_entry, false); | 1238 InsertOrReplaceEntry(new_entry, false); |
| 1231 } | 1239 } |
| 1232 | 1240 |
| 1233 bool NavigationControllerImpl::RendererDidNavigateAutoSubframe( | 1241 bool NavigationControllerImpl::RendererDidNavigateAutoSubframe( |
| 1234 RenderFrameHost* rfh, | 1242 RenderFrameHost* rfh, |
| 1243 int32 page_id, |
| 1235 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { | 1244 const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { |
| 1236 // We're guaranteed to have a previously committed entry, and we now need to | 1245 // We're guaranteed to have a previously committed entry, and we now need to |
| 1237 // handle navigation inside of a subframe in it without creating a new entry. | 1246 // handle navigation inside of a subframe in it without creating a new entry. |
| 1238 DCHECK(GetLastCommittedEntry()); | 1247 DCHECK(GetLastCommittedEntry()); |
| 1239 | 1248 |
| 1240 // Handle the case where we're navigating back/forward to a previous subframe | 1249 // Handle the case where we're navigating back/forward to a previous subframe |
| 1241 // navigation entry. This is case "2." in NAV_AUTO_SUBFRAME comment in the | 1250 // navigation entry. This is case "2." in NAV_AUTO_SUBFRAME comment in the |
| 1242 // header file. In case "1." this will be a NOP. | 1251 // header file. In case "1." this will be a NOP. |
| 1243 int entry_index = GetEntryIndexWithPageID( | 1252 int entry_index = GetEntryIndexWithPageID(rfh->GetSiteInstance(), page_id); |
| 1244 rfh->GetSiteInstance(), | |
| 1245 params.page_id); | |
| 1246 if (entry_index < 0 || | 1253 if (entry_index < 0 || |
| 1247 entry_index >= static_cast<int>(entries_.size())) { | 1254 entry_index >= static_cast<int>(entries_.size())) { |
| 1248 NOTREACHED(); | 1255 NOTREACHED(); |
| 1249 return false; | 1256 return false; |
| 1250 } | 1257 } |
| 1251 | 1258 |
| 1252 // Update the current navigation entry in case we're going back/forward. | 1259 // Update the current navigation entry in case we're going back/forward. |
| 1253 if (entry_index != last_committed_entry_index_) { | 1260 if (entry_index != last_committed_entry_index_) { |
| 1254 last_committed_entry_index_ = entry_index; | 1261 last_committed_entry_index_ = entry_index; |
| 1255 DiscardNonCommittedEntriesInternal(); | 1262 DiscardNonCommittedEntriesInternal(); |
| (...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1790 } | 1797 } |
| 1791 } | 1798 } |
| 1792 } | 1799 } |
| 1793 | 1800 |
| 1794 void NavigationControllerImpl::SetGetTimestampCallbackForTest( | 1801 void NavigationControllerImpl::SetGetTimestampCallbackForTest( |
| 1795 const base::Callback<base::Time()>& get_timestamp_callback) { | 1802 const base::Callback<base::Time()>& get_timestamp_callback) { |
| 1796 get_timestamp_callback_ = get_timestamp_callback; | 1803 get_timestamp_callback_ = get_timestamp_callback; |
| 1797 } | 1804 } |
| 1798 | 1805 |
| 1799 } // namespace content | 1806 } // namespace content |
| OLD | NEW |