OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/web_contents/navigation_controller_impl.h" | 5 #include "content/browser/web_contents/navigation_controller_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/string_number_conversions.h" // Temporary | 9 #include "base/string_number_conversions.h" // Temporary |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 1187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1198 } | 1198 } |
1199 | 1199 |
1200 FinishRestore(source.last_committed_entry_index_, RESTORE_CURRENT_SESSION); | 1200 FinishRestore(source.last_committed_entry_index_, RESTORE_CURRENT_SESSION); |
1201 | 1201 |
1202 // Copy the max page id map from the old tab to the new tab. This ensures | 1202 // Copy the max page id map from the old tab to the new tab. This ensures |
1203 // that new and existing navigations in the tab's current SiteInstances | 1203 // that new and existing navigations in the tab's current SiteInstances |
1204 // are identified properly. | 1204 // are identified properly. |
1205 web_contents_->CopyMaxPageIDsFrom(source.web_contents()); | 1205 web_contents_->CopyMaxPageIDsFrom(source.web_contents()); |
1206 } | 1206 } |
1207 | 1207 |
1208 void NavigationControllerImpl::CopyStateFromAndPrune( | 1208 bool NavigationControllerImpl::CopyStateFromAndPrune( |
1209 NavigationController* temp) { | 1209 NavigationController* temp) { |
1210 if (!CanPruneAllButVisible()) { | |
1211 // It is up to callers to check the invariants before calling this. | |
1212 NOTREACHED(); | |
1213 return false; | |
1214 } | |
1215 | |
1210 NavigationControllerImpl* source = | 1216 NavigationControllerImpl* source = |
1211 static_cast<NavigationControllerImpl*>(temp); | 1217 static_cast<NavigationControllerImpl*>(temp); |
1212 // The SiteInstance and page_id of the last committed entry needs to be | 1218 // The SiteInstance and page_id of the last committed entry needs to be |
1213 // remembered at this point, in case there is only one committed entry | 1219 // remembered at this point, in case there is only one committed entry |
1214 // and it is pruned. We use a scoped_refptr to ensure the SiteInstance | 1220 // and it is pruned. We use a scoped_refptr to ensure the SiteInstance |
1215 // can't be freed during this time period. | 1221 // can't be freed during this time period. |
1216 NavigationEntryImpl* last_committed = | 1222 NavigationEntryImpl* last_committed = |
1217 NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry()); | 1223 NavigationEntryImpl::FromNavigationEntry(GetLastCommittedEntry()); |
1218 scoped_refptr<SiteInstance> site_instance( | 1224 scoped_refptr<SiteInstance> site_instance( |
1219 last_committed ? last_committed->site_instance() : NULL); | 1225 last_committed->site_instance()); |
1220 int32 minimum_page_id = last_committed ? last_committed->GetPageID() : -1; | 1226 int32 minimum_page_id = last_committed->GetPageID(); |
1221 int32 max_page_id = last_committed ? | 1227 int32 max_page_id = |
1222 web_contents_->GetMaxPageIDForSiteInstance(site_instance.get()) : -1; | 1228 web_contents_->GetMaxPageIDForSiteInstance(site_instance.get()); |
1223 | 1229 |
1224 // This code is intended for use when the last entry is the active entry. | 1230 // This code is intended for use when the last entry is the active entry. |
1225 DCHECK( | 1231 DCHECK_EQ(GetEntryCount() - 1, last_committed_entry_index_); |
cbentzel
2013/05/17 00:32:15
I understand this was in here before. I think the
Charlie Reis
2013/05/17 23:50:21
We can't put it in CanPruneAllButVisible, because
| |
1226 (transient_entry_index_ != -1 && | |
1227 transient_entry_index_ == GetEntryCount() - 1) || | |
1228 (pending_entry_ && (pending_entry_index_ == -1 || | |
1229 pending_entry_index_ == GetEntryCount() - 1)) || | |
1230 (!pending_entry_ && last_committed_entry_index_ == GetEntryCount() - 1)); | |
1231 | 1232 |
1232 // Remove all the entries leaving the active entry. | 1233 // Remove all the entries leaving the active entry. |
1233 PruneAllButActiveInternal(); | 1234 if (!PruneAllButVisibleInternal()) |
1235 return false; | |
1234 | 1236 |
1235 // We now have zero or one entries. Ensure that adding the entries from | 1237 // We now have one entry, possibly with a new pending entry. Ensure that |
1236 // source won't put us over the limit. | 1238 // adding the entries from source won't put us over the limit. |
1237 DCHECK(GetEntryCount() == 0 || GetEntryCount() == 1); | 1239 DCHECK_EQ(1, GetEntryCount()); |
1238 if (GetEntryCount() > 0) | 1240 source->PruneOldestEntryIfFull(); |
1239 source->PruneOldestEntryIfFull(); | |
1240 | 1241 |
1241 // Insert the entries from source. Don't use source->GetCurrentEntryIndex as | 1242 // Insert the entries from source. Don't use source->GetCurrentEntryIndex as |
1242 // we don't want to copy over the transient entry. | 1243 // we don't want to copy over the transient entry. Ignore any pending entry, |
1243 int max_source_index = source->pending_entry_index_ != -1 ? | 1244 // since it has not committed in source. |
1244 source->pending_entry_index_ : source->last_committed_entry_index_; | 1245 int max_source_index = source->last_committed_entry_index_; |
1245 if (max_source_index == -1) | 1246 if (max_source_index == -1) |
1246 max_source_index = source->GetEntryCount(); | 1247 max_source_index = source->GetEntryCount(); |
1247 else | 1248 else |
1248 max_source_index++; | 1249 max_source_index++; |
1249 InsertEntriesFrom(*source, max_source_index); | 1250 InsertEntriesFrom(*source, max_source_index); |
1250 | 1251 |
1251 // Adjust indices such that the last entry and pending are at the end now. | 1252 // Adjust indices such that the last entry and pending are at the end now. |
1252 last_committed_entry_index_ = GetEntryCount() - 1; | 1253 last_committed_entry_index_ = GetEntryCount() - 1; |
1253 if (pending_entry_index_ != -1) | |
1254 pending_entry_index_ = GetEntryCount() - 1; | |
1255 if (transient_entry_index_ != -1) { | |
1256 // There's a transient entry. In this case we want the last committed to | |
1257 // point to the previous entry. | |
1258 transient_entry_index_ = GetEntryCount() - 1; | |
1259 if (last_committed_entry_index_ != -1) | |
1260 last_committed_entry_index_--; | |
1261 } | |
1262 | 1254 |
1263 web_contents_->SetHistoryLengthAndPrune(site_instance.get(), | 1255 web_contents_->SetHistoryLengthAndPrune(site_instance.get(), |
1264 max_source_index, | 1256 max_source_index, |
1265 minimum_page_id); | 1257 minimum_page_id); |
1266 | 1258 |
1267 // Copy the max page id map from the old tab to the new tab. This ensures | 1259 // Copy the max page id map from the old tab to the new tab. This ensures |
1268 // that new and existing navigations in the tab's current SiteInstances | 1260 // that new and existing navigations in the tab's current SiteInstances |
1269 // are identified properly. | 1261 // are identified properly. |
1270 web_contents_->CopyMaxPageIDsFrom(source->web_contents()); | 1262 web_contents_->CopyMaxPageIDsFrom(source->web_contents()); |
1271 | 1263 |
1272 // If there is a last committed entry, be sure to include it in the new | 1264 // If there is a last committed entry, be sure to include it in the new |
1273 // max page ID map. | 1265 // max page ID map. |
1274 if (max_page_id > -1) { | 1266 if (max_page_id > -1) { |
1275 web_contents_->UpdateMaxPageIDForSiteInstance(site_instance.get(), | 1267 web_contents_->UpdateMaxPageIDForSiteInstance(site_instance.get(), |
1276 max_page_id); | 1268 max_page_id); |
1277 } | 1269 } |
1270 | |
1271 return true; | |
1278 } | 1272 } |
1279 | 1273 |
1280 void NavigationControllerImpl::PruneAllButActive() { | 1274 bool NavigationControllerImpl::CanPruneAllButVisible() { |
1281 PruneAllButActiveInternal(); | 1275 // If there is no last committed entry, we cannot prune. Even if there is a |
1276 // pending entry, it may not commit, leaving this WebContents blank, despite | |
1277 // possibly giving it new entries via CopyStateFromAndPrune. | |
1278 if (last_committed_entry_index_ == -1) | |
1279 return false; | |
1282 | 1280 |
1283 // If there is an entry left, we need to update the session history length of | 1281 // We cannot prune if there is a pending entry at an existing entry index. |
1284 // the RenderView. | 1282 // It may not commit, so we have to keep the last committed entry, and thus |
1285 if (!GetActiveEntry()) | 1283 // there is no sensible place to keep the pending entry. It is ok to have |
1286 return; | 1284 // a new pending entry, which can optionally commit as a new navigation. |
1285 if (pending_entry_index_ != -1) | |
1286 return false; | |
1287 | |
1288 // We should not prune if we are currently showing a transient entry. | |
1289 if (transient_entry_index_ != -1) | |
1290 return false; | |
1291 | |
1292 return true; | |
1293 } | |
1294 | |
1295 bool NavigationControllerImpl::PruneAllButVisible() { | |
1296 if (!PruneAllButVisibleInternal()) | |
1297 return false; | |
1298 | |
1299 // We should still have a last committed entry. | |
1300 DCHECK_NE(-1, last_committed_entry_index_); | |
1287 | 1301 |
1288 NavigationEntryImpl* entry = | 1302 NavigationEntryImpl* entry = |
1289 NavigationEntryImpl::FromNavigationEntry(GetActiveEntry()); | 1303 NavigationEntryImpl::FromNavigationEntry(GetActiveEntry()); |
1290 // We pass 0 instead of GetEntryCount() for the history_length parameter of | 1304 // We pass 0 instead of GetEntryCount() for the history_length parameter of |
1291 // SetHistoryLengthAndPrune, because it will create history_length additional | 1305 // SetHistoryLengthAndPrune, because it will create history_length additional |
1292 // history entries. | 1306 // history entries. |
1293 // TODO(jochen): This API is confusing and we should clean it up. | 1307 // TODO(jochen): This API is confusing and we should clean it up. |
1294 // http://crbug.com/178491 | 1308 // http://crbug.com/178491 |
1295 web_contents_->SetHistoryLengthAndPrune( | 1309 web_contents_->SetHistoryLengthAndPrune( |
1296 entry->site_instance(), 0, entry->GetPageID()); | 1310 entry->site_instance(), 0, entry->GetPageID()); |
1311 | |
1312 return true; | |
1297 } | 1313 } |
1298 | 1314 |
1299 void NavigationControllerImpl::PruneAllButActiveInternal() { | 1315 bool NavigationControllerImpl::PruneAllButVisibleInternal() { |
1300 if (transient_entry_index_ != -1) { | 1316 if (!CanPruneAllButVisible()) { |
cbentzel
2013/05/17 00:32:15
Should this just be a DCHECK? The only callers are
Charlie Reis
2013/05/17 23:50:21
The public PruneAllButVisible doesn't call CanPrun
| |
1301 // There is a transient entry. Prune up to it. | 1317 // It is up to callers to check the invariants before calling this. |
1302 DCHECK_EQ(GetEntryCount() - 1, transient_entry_index_); | 1318 NOTREACHED(); |
1303 entries_.erase(entries_.begin(), entries_.begin() + transient_entry_index_); | 1319 return false; |
1304 transient_entry_index_ = 0; | |
1305 last_committed_entry_index_ = -1; | |
1306 pending_entry_index_ = -1; | |
1307 } else if (!pending_entry_) { | |
1308 // There's no pending entry. Leave the last entry (if there is one). | |
1309 if (!GetEntryCount()) | |
1310 return; | |
1311 | |
1312 DCHECK_GE(last_committed_entry_index_, 0); | |
1313 entries_.erase(entries_.begin(), | |
1314 entries_.begin() + last_committed_entry_index_); | |
1315 entries_.erase(entries_.begin() + 1, entries_.end()); | |
1316 last_committed_entry_index_ = 0; | |
1317 } else if (pending_entry_index_ != -1) { | |
1318 entries_.erase(entries_.begin(), entries_.begin() + pending_entry_index_); | |
1319 entries_.erase(entries_.begin() + 1, entries_.end()); | |
1320 pending_entry_index_ = 0; | |
1321 last_committed_entry_index_ = 0; | |
1322 } else { | |
1323 // There is a pending_entry, but it's not in entries_. | |
1324 pending_entry_index_ = -1; | |
1325 last_committed_entry_index_ = -1; | |
1326 entries_.clear(); | |
1327 } | 1320 } |
1328 | 1321 |
1329 if (web_contents_->GetInterstitialPage()) { | 1322 // Erase all entries but the last committed entry. There may still be a |
1330 // Normally the interstitial page hides itself if the user doesn't proceeed. | 1323 // new pending entry after this. |
1331 // This would result in showing a NavigationEntry we just removed. Set this | 1324 entries_.erase(entries_.begin(), |
1332 // so the interstitial triggers a reload if the user doesn't proceed. | 1325 entries_.begin() + last_committed_entry_index_); |
1333 static_cast<InterstitialPageImpl*>(web_contents_->GetInterstitialPage())-> | 1326 entries_.erase(entries_.begin() + 1, entries_.end()); |
1334 set_reload_on_dont_proceed(true); | 1327 last_committed_entry_index_ = 0; |
1335 } | 1328 |
1329 return true; | |
1336 } | 1330 } |
1337 | 1331 |
1338 void NavigationControllerImpl::ClearAllScreenshots() { | 1332 void NavigationControllerImpl::ClearAllScreenshots() { |
1339 screenshot_manager_->ClearAllScreenshots(); | 1333 screenshot_manager_->ClearAllScreenshots(); |
1340 } | 1334 } |
1341 | 1335 |
1342 void NavigationControllerImpl::SetSessionStorageNamespace( | 1336 void NavigationControllerImpl::SetSessionStorageNamespace( |
1343 const std::string& partition_id, | 1337 const std::string& partition_id, |
1344 SessionStorageNamespace* session_storage_namespace) { | 1338 SessionStorageNamespace* session_storage_namespace) { |
1345 if (!session_storage_namespace) | 1339 if (!session_storage_namespace) |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1677 } | 1671 } |
1678 } | 1672 } |
1679 } | 1673 } |
1680 | 1674 |
1681 void NavigationControllerImpl::SetGetTimestampCallbackForTest( | 1675 void NavigationControllerImpl::SetGetTimestampCallbackForTest( |
1682 const base::Callback<base::Time()>& get_timestamp_callback) { | 1676 const base::Callback<base::Time()>& get_timestamp_callback) { |
1683 get_timestamp_callback_ = get_timestamp_callback; | 1677 get_timestamp_callback_ = get_timestamp_callback; |
1684 } | 1678 } |
1685 | 1679 |
1686 } // namespace content | 1680 } // namespace content |
OLD | NEW |