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 /* | 5 /* |
6 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | 6 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
7 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 7 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. | 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. |
9 * (http://www.torchmobile.com/) | 9 * (http://www.torchmobile.com/) |
10 * | 10 * |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 SetPageStateIfEmpty((*entries)[i].get()); | 128 SetPageStateIfEmpty((*entries)[i].get()); |
129 } | 129 } |
130 } | 130 } |
131 | 131 |
132 // Determines whether or not we should be carrying over a user agent override | 132 // Determines whether or not we should be carrying over a user agent override |
133 // between two NavigationEntries. | 133 // between two NavigationEntries. |
134 bool ShouldKeepOverride(const NavigationEntry* last_entry) { | 134 bool ShouldKeepOverride(const NavigationEntry* last_entry) { |
135 return last_entry && last_entry->GetIsOverridingUserAgent(); | 135 return last_entry && last_entry->GetIsOverridingUserAgent(); |
136 } | 136 } |
137 | 137 |
| 138 // Returns true if the PageTransition in the |entry| require this navigation to |
| 139 // be treated as a reload. For e.g. navigating to the last committed url via |
| 140 // the address bar or clicking on a link which results in a navigation to the |
| 141 // last committed or pending navigation, etc. |
| 142 bool ShouldTreatNavigationAsReload(const NavigationEntry* entry) { |
| 143 if (!entry) |
| 144 return false; |
| 145 |
| 146 // We treat (PAGE_TRANSITION_RELOAD | PAGE_TRANSITION_FROM_ADDRESS_BAR), |
| 147 // PAGE_TRANSITION_TYPED or PAGE_TRANSITION_LINK transitions as navigations |
| 148 // which should be treated as reloads. |
| 149 if ((ui::PageTransitionCoreTypeIs(entry->GetTransitionType(), |
| 150 ui::PAGE_TRANSITION_RELOAD) && |
| 151 (entry->GetTransitionType() & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR))) { |
| 152 return true; |
| 153 } |
| 154 |
| 155 if (ui::PageTransitionCoreTypeIs(entry->GetTransitionType(), |
| 156 ui::PAGE_TRANSITION_TYPED)) { |
| 157 return true; |
| 158 } |
| 159 |
| 160 if (ui::PageTransitionCoreTypeIs(entry->GetTransitionType(), |
| 161 ui::PAGE_TRANSITION_LINK)) { |
| 162 return true; |
| 163 } |
| 164 return false; |
| 165 } |
| 166 |
138 } // namespace | 167 } // namespace |
139 | 168 |
140 // NavigationControllerImpl ---------------------------------------------------- | 169 // NavigationControllerImpl ---------------------------------------------------- |
141 | 170 |
142 const size_t kMaxEntryCountForTestingNotSet = static_cast<size_t>(-1); | 171 const size_t kMaxEntryCountForTestingNotSet = static_cast<size_t>(-1); |
143 | 172 |
144 // static | 173 // static |
145 size_t NavigationControllerImpl::max_entry_count_for_testing_ = | 174 size_t NavigationControllerImpl::max_entry_count_for_testing_ = |
146 kMaxEntryCountForTestingNotSet; | 175 kMaxEntryCountForTestingNotSet; |
147 | 176 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 // Otherwise, we're clear of the last duplicate run, so reset the | 234 // Otherwise, we're clear of the last duplicate run, so reset the |
206 // water marks. | 235 // water marks. |
207 low_water_mark_ = high_water_mark_ = t; | 236 low_water_mark_ = high_water_mark_ = t; |
208 return t; | 237 return t; |
209 } | 238 } |
210 | 239 |
211 NavigationControllerImpl::NavigationControllerImpl( | 240 NavigationControllerImpl::NavigationControllerImpl( |
212 NavigationControllerDelegate* delegate, | 241 NavigationControllerDelegate* delegate, |
213 BrowserContext* browser_context) | 242 BrowserContext* browser_context) |
214 : browser_context_(browser_context), | 243 : browser_context_(browser_context), |
215 pending_entry_(NULL), | 244 pending_entry_(nullptr), |
| 245 last_pending_entry_(nullptr), |
216 failed_pending_entry_id_(0), | 246 failed_pending_entry_id_(0), |
217 last_committed_entry_index_(-1), | 247 last_committed_entry_index_(-1), |
218 pending_entry_index_(-1), | 248 pending_entry_index_(-1), |
219 transient_entry_index_(-1), | 249 transient_entry_index_(-1), |
| 250 last_pending_entry_index_(-1), |
| 251 last_transient_entry_index_(-1), |
220 delegate_(delegate), | 252 delegate_(delegate), |
221 ssl_manager_(this), | 253 ssl_manager_(this), |
222 needs_reload_(false), | 254 needs_reload_(false), |
223 is_initial_navigation_(true), | 255 is_initial_navigation_(true), |
224 in_navigate_to_pending_entry_(false), | 256 in_navigate_to_pending_entry_(false), |
225 pending_reload_(ReloadType::NONE), | 257 pending_reload_(ReloadType::NONE), |
226 get_timestamp_callback_(base::Bind(&base::Time::Now)), | 258 get_timestamp_callback_(base::Bind(&base::Time::Now)), |
227 screenshot_manager_(new NavigationEntryScreenshotManager(this)), | 259 screenshot_manager_(new NavigationEntryScreenshotManager(this)), |
228 last_committed_reload_type_(ReloadType::NONE) { | 260 last_committed_reload_type_(ReloadType::NONE) { |
229 DCHECK(browser_context_); | 261 DCHECK(browser_context_); |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 } | 451 } |
420 | 452 |
421 NavigationEntryImpl* | 453 NavigationEntryImpl* |
422 NavigationControllerImpl::GetEntryWithUniqueID(int nav_entry_id) const { | 454 NavigationControllerImpl::GetEntryWithUniqueID(int nav_entry_id) const { |
423 int index = GetEntryIndexWithUniqueID(nav_entry_id); | 455 int index = GetEntryIndexWithUniqueID(nav_entry_id); |
424 return (index != -1) ? entries_[index].get() : nullptr; | 456 return (index != -1) ? entries_[index].get() : nullptr; |
425 } | 457 } |
426 | 458 |
427 void NavigationControllerImpl::LoadEntry( | 459 void NavigationControllerImpl::LoadEntry( |
428 std::unique_ptr<NavigationEntryImpl> entry) { | 460 std::unique_ptr<NavigationEntryImpl> entry) { |
| 461 // Remember the last pending entry for which we haven't received a response |
| 462 // yet. This will be deleted in the NavigateToPendingEntry() function. |
| 463 last_pending_entry_ = pending_entry_; |
| 464 last_pending_entry_index_ = pending_entry_index_; |
| 465 last_transient_entry_index_ = transient_entry_index_; |
| 466 pending_entry_ = nullptr; |
429 // When navigating to a new page, we don't know for sure if we will actually | 467 // When navigating to a new page, we don't know for sure if we will actually |
430 // end up leaving the current page. The new page load could for example | 468 // end up leaving the current page. The new page load could for example |
431 // result in a download or a 'no content' response (e.g., a mailto: URL). | 469 // result in a download or a 'no content' response (e.g., a mailto: URL). |
432 SetPendingEntry(std::move(entry)); | 470 SetPendingEntry(std::move(entry)); |
433 NavigateToPendingEntry(ReloadType::NONE); | 471 NavigateToPendingEntry(ReloadType::NONE); |
434 } | 472 } |
435 | 473 |
436 void NavigationControllerImpl::SetPendingEntry( | 474 void NavigationControllerImpl::SetPendingEntry( |
437 std::unique_ptr<NavigationEntryImpl> entry) { | 475 std::unique_ptr<NavigationEntryImpl> entry) { |
438 DiscardNonCommittedEntriesInternal(); | 476 DiscardNonCommittedEntriesInternal(); |
(...skipping 1332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1771 | 1809 |
1772 DiscardNonCommittedEntries(); | 1810 DiscardNonCommittedEntries(); |
1773 return; | 1811 return; |
1774 } | 1812 } |
1775 | 1813 |
1776 // If an interstitial page is showing, the previous renderer is blocked and | 1814 // If an interstitial page is showing, the previous renderer is blocked and |
1777 // cannot make new requests. Unblock (and disable) it to allow this | 1815 // cannot make new requests. Unblock (and disable) it to allow this |
1778 // navigation to succeed. The interstitial will stay visible until the | 1816 // navigation to succeed. The interstitial will stay visible until the |
1779 // resulting DidNavigate. | 1817 // resulting DidNavigate. |
1780 if (delegate_->GetInterstitialPage()) { | 1818 if (delegate_->GetInterstitialPage()) { |
1781 static_cast<InterstitialPageImpl*>(delegate_->GetInterstitialPage())-> | 1819 static_cast<InterstitialPageImpl*>(delegate_->GetInterstitialPage()) |
1782 CancelForNavigation(); | 1820 ->CancelForNavigation(); |
1783 } | 1821 } |
1784 | 1822 |
| 1823 // The last navigation is the last pending navigation which hasn't been |
| 1824 // committed yet, or the last committed navigation. |
| 1825 NavigationEntryImpl* last_navigation = |
| 1826 last_pending_entry_ ? last_pending_entry_ : GetLastCommittedEntry(); |
| 1827 |
| 1828 // Convert Enter-in-omnibox to a reload. This is what Blink does in |
| 1829 // FrameLoader, but we want to handle it here so that if the navigation is |
| 1830 // redirected or handled purely on the browser side in PlzNavigate we have the |
| 1831 // same behaviour as Blink would. Note that we don't want to convert to a |
| 1832 // reload for history navigations, so this must be above the retrieval of the |
| 1833 // pending_entry_ below when pending_entry_index_ is used. |
| 1834 if (reload_type == ReloadType::NONE && last_navigation && pending_entry_ && |
| 1835 // Please refer to the ShouldTreatNavigationAsReload() function for info |
| 1836 // on which navigations are treated as reloads. In general navigating to |
| 1837 // the last committed or pending entry via the address bar, clicking on |
| 1838 // a link, etc would be treated as reloads. |
| 1839 ShouldTreatNavigationAsReload(pending_entry_) && |
| 1840 // Skip entries with SSL errors. |
| 1841 !last_navigation->ssl_error() && |
| 1842 // Ignore interstitial pages |
| 1843 last_transient_entry_index_ == -1 && |
| 1844 pending_entry_->frame_tree_node_id() == -1 && |
| 1845 pending_entry_->GetURL() == last_navigation->GetURL() && |
| 1846 !pending_entry_->GetHasPostData() && !last_navigation->GetHasPostData() && |
| 1847 // This check is required for cases like view-source:, etc. Here the URL |
| 1848 // of the navigation entry would contain the url of the page, while the |
| 1849 // virtual URL contains the full URL including the view-source prefix. |
| 1850 last_navigation->GetVirtualURL() == pending_entry_->GetVirtualURL() && |
| 1851 // This check is required for Android WebView loadDataWithBaseURL. Apps |
| 1852 // can pass in anything in the base URL and we need to ensure that these |
| 1853 // match before classifying it as a reload. |
| 1854 (pending_entry_->GetURL().SchemeIs(url::kDataScheme) && |
| 1855 pending_entry_->GetBaseURLForDataURL().is_valid() |
| 1856 ? pending_entry_->GetBaseURLForDataURL() == |
| 1857 last_navigation->GetBaseURLForDataURL() |
| 1858 : true)) { |
| 1859 reload_type = ReloadType::NORMAL; |
| 1860 } |
| 1861 |
| 1862 if (last_pending_entry_index_ == -1 && last_pending_entry_) |
| 1863 delete last_pending_entry_; |
| 1864 |
| 1865 last_transient_entry_index_ = -1; |
| 1866 last_pending_entry_ = nullptr; |
| 1867 last_pending_entry_index_ = -1; |
| 1868 |
1785 // For session history navigations only the pending_entry_index_ is set. | 1869 // For session history navigations only the pending_entry_index_ is set. |
1786 if (!pending_entry_) { | 1870 if (!pending_entry_) { |
1787 CHECK_NE(pending_entry_index_, -1); | 1871 CHECK_NE(pending_entry_index_, -1); |
1788 pending_entry_ = entries_[pending_entry_index_].get(); | 1872 pending_entry_ = entries_[pending_entry_index_].get(); |
1789 } | 1873 } |
1790 | 1874 |
1791 // Any renderer-side debug URLs or javascript: URLs should be ignored if the | 1875 // Any renderer-side debug URLs or javascript: URLs should be ignored if the |
1792 // renderer process is not live, unless it is the initial navigation of the | 1876 // renderer process is not live, unless it is the initial navigation of the |
1793 // tab. | 1877 // tab. |
1794 if (IsRendererDebugURL(pending_entry_->GetURL())) { | 1878 if (IsRendererDebugURL(pending_entry_->GetURL())) { |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2017 } else { | 2101 } else { |
2018 failed_pending_entry_id_ = 0; | 2102 failed_pending_entry_id_ = 0; |
2019 } | 2103 } |
2020 | 2104 |
2021 if (pending_entry_index_ == -1) | 2105 if (pending_entry_index_ == -1) |
2022 delete pending_entry_; | 2106 delete pending_entry_; |
2023 pending_entry_ = NULL; | 2107 pending_entry_ = NULL; |
2024 pending_entry_index_ = -1; | 2108 pending_entry_index_ = -1; |
2025 } | 2109 } |
2026 | 2110 |
| 2111 void NavigationControllerImpl::SetPendingNavigationSSLError(bool error) { |
| 2112 if (pending_entry_) |
| 2113 pending_entry_->set_ssl_error(error); |
| 2114 } |
| 2115 |
2027 void NavigationControllerImpl::DiscardTransientEntry() { | 2116 void NavigationControllerImpl::DiscardTransientEntry() { |
2028 if (transient_entry_index_ == -1) | 2117 if (transient_entry_index_ == -1) |
2029 return; | 2118 return; |
2030 entries_.erase(entries_.begin() + transient_entry_index_); | 2119 entries_.erase(entries_.begin() + transient_entry_index_); |
2031 if (last_committed_entry_index_ > transient_entry_index_) | 2120 if (last_committed_entry_index_ > transient_entry_index_) |
2032 last_committed_entry_index_--; | 2121 last_committed_entry_index_--; |
2033 transient_entry_index_ = -1; | 2122 transient_entry_index_ = -1; |
2034 } | 2123 } |
2035 | 2124 |
2036 int NavigationControllerImpl::GetEntryIndexWithUniqueID( | 2125 int NavigationControllerImpl::GetEntryIndexWithUniqueID( |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2077 } | 2166 } |
2078 } | 2167 } |
2079 } | 2168 } |
2080 | 2169 |
2081 void NavigationControllerImpl::SetGetTimestampCallbackForTest( | 2170 void NavigationControllerImpl::SetGetTimestampCallbackForTest( |
2082 const base::Callback<base::Time()>& get_timestamp_callback) { | 2171 const base::Callback<base::Time()>& get_timestamp_callback) { |
2083 get_timestamp_callback_ = get_timestamp_callback; | 2172 get_timestamp_callback_ = get_timestamp_callback; |
2084 } | 2173 } |
2085 | 2174 |
2086 } // namespace content | 2175 } // namespace content |
OLD | NEW |